函数基础~~

一、函数/方法【重点掌握】

1.函数基本使用:

​ 定义

​ 调用

​ 参数

​ 返回值

​ 匿名函数

2.函数进阶使用

​ 闭包

​ 变量的作用域

​ 高阶函数

​ 装饰器【难点,重点】

​ 递归

函数:function

方法:method

1.概述

在一个完整的项目中,某些功能可能会被反复使用,如果将反复出现的代码封装成函数,以后如果要继续使用该功能则直接使用函数即可,另外,如果要修改需求,只需要修改函数

本质:对某些特殊功能的封装

优点:

​ a.简化代码结构,提高应用的模块性

​ b.提高了代码的复用性

​ c.提高了代码维护性

# 需求:求圆的面积

# 1.
r1 = 45
area1 = 3.14 * r1 ** 2
print(area1)

r2 = 10
area2 = 3.14 * r2 ** 2
print(area2)

r3 = 5
area3 = 3.14 * r3 ** 2
print(area3)


# 2.优化
# 本质:对某些特殊功能的封装
def area(r):
    return 3.14 * r ** 2

print(area(45))
print(area(10))
print(area(5))

"""
优点:
	a.简化代码结构,提高应用的模块性

	b.提高了代码的复用性

	c.提高了代码维护性
"""
2.定义

语法:

​ def 函数名(变量1,变量2…):

​ 函数体

​ return 返回值

说明:

​ a.def是一个关键字,是definition的缩写,专门定义函数

​ b.函数名:遵循合法标识符的规则和规范即可,尽量做到见名知意

​ c.(变量1,变量2…):被称为形式参数,是一个参数列表,都只是没有赋值的变量

​ d.函数体:封装某些特殊的功能

​ e.return是一个关键字,表示返回,只能用在函数中,表示结束函数,可以单独使用,也可以携带数据,当携带数据,则表示该函数的返回值

​ f.返回值:常量,变量,表达式

​ g.函数的定义分为两部分:函数的声明和函数的实现

​ h.变量1,变量2… 和 return 返回值 可以根据具体的需求选择性的省略

"""
语法:

	def  函数名(变量1,变量2....):

		    函数体

		    return   返回值

说明:

	a.def是一个关键字,是definition的缩写,专门定义函数

	b.函数名:遵循合法标识符的规则和规范即可,尽量做到见名知意

	c.(变量1,变量2....):被称为形式参数,是一个参数列表,都只是没有赋值的变量

	d.函数体:封装某些特殊的功能

	e.return是一个关键字,表示返回,只能用在函数中,表示结束函数,可以单独使用,也可以携带数据,当携带数据,则表示该函数的返回值

	f.返回值:常量,变量,表达式

	g.函数的定义分为两部分:函数的声明和函数的实现

	h.变量1,变量2.... 和 return   返回值 可以根据具体的需求选择性的省略

"""

print("start")

# 1.基本语法
# a.函数的声明部分
def test():
    # b.函数的实现部分
    print("1111")

# 2.函数不同形式的定义
# a.无参无返回值的函数
def func1():
    print("func~~111")

# b.有参无返回值的函数
def func2(a,b):
    print("func~~~~~222")

# c.无参有返回值的函数
def func3():
    return "abc"

# d.有参有返回值的函数
def func4(num1,num2):
    return num1 + num2

print("end")

"""
总结:
    a.函数和if语句,while循环,以及for循环相似,都是代码块的操作
    b.定义函数的过程相当于定义变量的过程,只是将函数加载到了内存中
    c.一个函数一旦定义完成,则需要手动调用,否则不会执行
"""
3.调用
"""
函数的定义:
    def  函数名(形式参数):
            函数体
            return   返回值

函数的调用:
    函数名(实际参数)

形式参数:出现在函数的声明部分,简称形参,可以理解为是一个等待赋值的变量
实际参数:出现在函数的调用部分,简称实参,实参就是给形参赋值的数据

调用函数的过程实际上就是传参的过程
传参的过程:实参给形参赋值的过程,如果没有形参,则也没有实参,二者需要匹配
"""

# 1.
print("start")

def func1():
    print("func~~111")

func1()
func1()
func1()
func1()
func1()
func1()

print("end")

# 函数调用的工作原理:代码从上往下依次执行,一旦遇到函数的调用,则去执行相应的函数,
# 当函数执行完毕,则程序回到函数调用的位置接着执行后面的代码

# 系统函数的调用
list1 = [34,6,7]
list1.append(10)
list1.insert(1,66)

# 2.
def func1():
    print("111")
    func2()
def func2():
    func3()
    print("222")
def func3():
    func4()
    print("333")
def func4():
    print("444")

func1()

"""
注意:在py文件中可以直接调用函数,
     函数之间也可以相互调用
"""

# 3.错误操作
# a.函数自己调用自己,恶性调用
# def test():
#     print("ok")
#     test()
# test()


# b.两个函数之间相互调用,恶性调用
# def test1():
#     print("111")
#     test2()
# def test2():
#     print("222")
#     test1()
# test1()
4.参数
4.1参数分类

形式参数:简称形参,定义在函数的声明部分,本质是一个没有值的变量,用于接收实参的值

实际参数:简称实参,出现在函数的调用过程中,本质是一个有值的变量或者常量,用于给形参赋值

传参:实参给形参赋值的过程

参数分类:

  • 必需参数

  • 默认参数

  • 关键字参数

  • 不定长参数【可变参数】

# 1.必需参数
# a.注意1:必需参数传参的时候,一定要注意数量的匹配
def func1():
    print("func~~~1111")
func1()
# func1(34)   # TypeError: func1() takes 0 positional arguments but 1 was given

# b
def func2(a):
    print("func~~~222",a)
# func2()       # TypeError: func2() missing 1 required positional argument: 'a'
func2(10)
func2("abc")

# c.注意2:必需参数传参的时候,一定要注意顺序的匹配
def func3(name,age):
    print(f"姓名:{name},年龄:{age}")
# func3(18,"jack")
func3("jack",18)

# d.注意3:必需参数传参的时候,一定要注意类型的匹配
def func4(name,age):
    print("姓名:%s,年龄:%d" % (name,age))
# func4("aaa","gahjg")  # TypeError: %d format: a number is required, not str
func4("张三",10)

print("*" * 30)


# 2.默认参数
# a.注意1:默认参数体现在形参上
def test1(a,b = 0):   # a是一个必需参数,b是一个默认参数
    print(a,b,a + b)
# 注意2:形参使用默认参数,如果实参给该参数未传参,则使用默认值
test1(3)
test1(3,5)    # 5会给b重新赋值


# b.
def test2(a = 0,b = 0,c = 0):
    print(a,b,c)
test2()
test2(2,6)
test2(3,4,6)

def test3(a,b = 0,c = 0):
    print(a,b,c)
test3(6)

def test4(a,b,c = 0):
    print(a,b,c)
test4(6,3)

# 注意3:如果形参有多个,可以必需参数和默认参数混合使用,但是在形参中,默认参数靠后书写
# def test4(a,b = 0,c):   # SyntaxError: non-default argument follows default argument
#     print(a,b,c)
# test4(6,3)

# 注意4:默认参数出现的意义就是为了简化函数的调用
# end默认值为\n
print(45)
print(60)
# print(34,end="*")


# 3.关键字参数
# 注意1:关键字参数体现在实参中
def check1(name,age,score):
    print(f"姓名:{name},年龄:{age},成绩:{score}")
# check1("jack",18,100)
# check1(18,"jack",100)  # 逻辑不通,姓名:18,年龄:jack,成绩:100

# 注意2:使用关键字参数传参可以不用匹配顺序,但是,关键字需要和形参的变量名保持一致
check1(age=18,name="jack",score=100)  # 姓名:jack,年龄:18,成绩:100
# check1(age=18,name1="jack",score=100)  # TypeError: check1() got an unexpected keyword argument 'name1'
check1('aaa',score=88,age=10)
check1("bbb",12,score=99)

# 注意3:在实参中,关键字参数只能书写在参数的后面
def check2(name,age,score):
    print(f"姓名:{name},年龄:{age},成绩:{score}")
# check2(name="tom",10,66)  # SyntaxError: positional argument follows keyword argument
# check2(10,66,name="tom")  # TypeError: check2() got multiple重复 values for argument 'name'

# 注意4:默认参数和关键字参数可以结合使用
def check3(name,age,score=0):
    print(f"姓名:{name},年龄:{age},成绩:{score}")
check3("jack",10)
check3("jack",10,67)
check3(name="jack",age=10,score=67)
check3("jack",age=10,score=67)
check3("jack",10,score=67)

print("*" * 30)


# 4.不定长参数/可变参数:可以接受不定长的参数
# a.*xxx,
# 注意1:*xxx,xxx被当成一个元组处理
def text1(*num):
    print(num)
text1()
text1(34)
text1(34,56,67,68,7,8)
text1(34,56,67,68,7,8,"abnfa",True)

# 注意2:必需参数可以和不定长参数混合使用
def text2(num1,*num2):
    print(num1,num2)
text2(10,45,56,67,6,8,7,8)

# 注意3:如果不定长参数出现在形参列表的前面,则可以结合关键字参数完成传参
def text3(*num1,num2):
    print(num1,num2)
# text3(10,45,56,67,6,8,7,8)  # TypeError: text3() missing 1 required keyword-only argument: 'num2'
text3(10,45,56,67,6,8,7,num2 = 8)


# 注意4:*xxx在形参列表中只能被使用一次
# def text4(*num1,*num2):
#     print(num1,num2)
# text4(45,57,6,77,8)

print("*" * 30)

# b.**xxx
# 注意1:**xxx,xxx会被当做字典处理
def f1(**num):
    print(num)

# 注意2:给**xxx的形参传参,则必须以key=value的方式传参
f1(x=10,y=20,z=30)  # {'x': 10, 'y': 20, 'z': 30}

# 注意3:**xxx在同一个函数的形参中只能出现一次
# def f2(**num1,**num2):
#     print(num1)
# f2(x=10,y=20,z=30)

# 注意4:*xxx和**xxx可以同时使用,但是,分别只能使用一次
def f3(*num1,**num2):
    print(num1,num2)
f3(45,45,65,7,67)
f3(45,45,65,7,67,a=4,b=467,fag="abc")
f3(a=4,b=467,fag="abc")

# 注意5:一般情况下,如果*xx和**xxx结合使用,命名为:*args,**kwargs
4.2参数传递
# 参数的传递:值传递和引用传递

"""
【面试题】简述值传递和引用传递的区别
值传递:传参的时候,传递的是不可变的数据类型,如:int/float/str/tuple/bool,当形参发生修改,对实参没有影响
引用传递:传参的时候,传递的是可变的数据类型,如:list/dict/set等,当形参中的元素发生修改,则实参会随着修改
"""

# 1.值传递
def func1(num):
    print(f"修改之前,num的地址:{id(num)}")
    num = 100
    print(f"修改之后,num的地址:{id(num)}~~~~")

temp = 45
func1(temp)
print(f"temp的值:{temp}")


print("*" * 50)


# 2.引用传递
def func1(num):
    print(f"修改之前,num的地址:{id(num)}")
    num[1] = 100
    print(f"修改之后,num的地址:{id(num)}~~~~")

temp = [2,3,4]
func1(temp)
print(f"temp的值:{temp}")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值