一、函数
面对在一个项目中很多地方需要的功能是相似的, 只要改变一些初始值就能实现. 我们可以将这一类的代码写在一起构成一个函数, 需要改变的初始值可以定义为函数的参数. 语法如下
def function_name(arg1,arg2,arg3=value1, arg3=value2, *args, **kwargs):
"""函数文档说明, 描述函数的功能及使用方法""" # 可以不写, 最好还是写上
函数执行语句
return value # 函数的返回值, 可以不写, 但是也会有一个默认返回值None
function_name(arg1,arg2,arg3=value1, arg3=value2) # 调用函数
- 函数文档说明: 用于解释或说明函数功能, 并提供函数的基本使用方法. 建议最好写上.
- return语句: 用于返回函数的值, 可选语句.
- 函数体: 函数执行的语句.
arg1 arg2
: 位置参数. 传入参数是, 必须按位置进行传参. 且必须传入参数才能调用arg3=value1, arg3=value2
: 关键值参数, 参数是有默认值的, 调用函数时可以不用传入参数.*args
: 不定长参数, 会将以位置参数形式的参数打包到一个元组里面.**kwargs
: 不定长参数, 会将默认参数形式的参数打包到一个字典中.- 调用函数时通过
函数名(参数)
进行函数的调用. 并且要将参数传入被调用函数 - 定义函数时, 参数一般按如下顺序排列:
位置参数(arg),/,关键值参数(key=value), 元组形式不定长参数(*args), 关键值形式不定长参数(**kwargs)
输出任意范围内的斐波拉且数列
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=" ")
a, b = b, a + b
print()
fib(1000)
n
: 参数- 返回值为,
None
二、函数的参数传递形式
默认情况下,函数的参数传递形式可以是位置参数或是显式的关键字参数
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=" ")
a, b = b, a + b
print()
fib(1000) # 位置参数
fib(n=1000) # 关键字参数
- 默认情况下, 这两种参数传递形式都是支持的。
为了提高代码的可读性和执行效率, 可以使用限制函数参数的传递形式
def function_name(pos_arg1,pos_arg2,/,pos_or_kwd_arg1, pos_or_kwd_arg2,*,kwd_arg1, kwd_arg2):
pass
/
之前的参数, 必须使用位置传参的形式*
之后的参数, 必须使用关键字传参的形式/
和*
之间的二者皆可使用
三、函数参数的传递机制
- 按值传递: 参数为不可变类型时, python会将实际参数(实参)值拷贝到被调用函数内部. 也即是在被顶用函数的内部新建对象, 将其赋值为实际参数的值. 和实际参数时完全独立的.
- 按引用传递(按地址传递): 参数为可变类型, python会将实际参数(实参)的id(地址)传递到函数内部
3.1 按值传递
a = 10
b = 20
def exchange(a, b):
a, b = b, a
print(f"exchange: a: {a},b: {b}")
exchange(a, b)
print(f"函数外部: a: {a}, b: {b}")
输出结果为:
exchange: a: 20,b: 10 函数外部: a: 10, b: 20
- 从结果看出这种不可变的数据类型作为参数传入函数时, 会在被调用函数内部新建一个对象, 它与函数内部无关
- 按引用调用
li = []
def add(li: list):
i = 0
while i < 10:
li.append(i := i+1)
print(f"add: li:{li}")
print(f"函数外部, 未调用add函数: li:{li}")
add(li)
print(f"函数外部, 调用add后: li:{li}")
函数运行结果: 函数外部, 未调用add函数: li:[] add: li:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 函数外部, 调用add后: li:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- 可变数据类型做参数时, 会将对象的id(地址)传递进入函数内部.
四、匿名函数
匿名函数能实现的功能比较的简单, 通常使用在需要函数作为参数的内置函数中 语法如下:
关键字(lambda) 参数: 返回值
x = 10
y = 20
fun = lambda x, y: x+y # 定义匿名函数 关键字(lambda) 参数: 返回值
x_y = fun(x,y)
print(x_y)
五、闭包
- 闭包是函数里面嵌套函数,外层函数返回里层函数,这种情况称之为闭包
- 闭包是概念,不是某种函数类型,和递归的概念类似,就是种特殊的函数调用
- 闭包可以得到外层函数的局部变量,是函数内部和函数外部沟通的桥梁
def func():
def text():
print("hello world")
return text
text = func() # 调用外层函数获取内层函数函数名
text() # 调用内层函数。