函数的定义和调用
def 函数标识符(形参):
函数体内容
return [内容,没有定义return值,返回None]
def test():
pass
def test1():
return 1
# x就是函数test2的形参
def test2(x):
return x**2
def test3()
return 1,2
a = test()
print(a) # 打印None
b = test1()
print(b) # 打印1
# test(2) 2就是实参
c = test2(2)
print(c) # 打印4
# 会把多个返回值封装成元祖,如果=左侧有多个标识符,可以解构赋值
d,e = test3()
print(d,e) # d=1,e=2
函数传参
传参方式
- 位置传参:严格按照参数位置传参,形参和实参的数量必须对应
def test(x, y, z):
print(x,y)
test(1,2) # 错误,因为参数有3个
test(1,2,3)
- 关键字传参:调用函数使用形参名字传入参数,可以与形参的顺序不同
def test(x, y, z):
print(x, y, z)
test(z=3, y=2, x=1)
- 注意:位置传参必须在关键字传参前
def test(x, y, z):
print(x, y, z)
test(1, 2, 3)
test(z=3, y=2, x=1)
test(y=2, x=1, z=3)
test(1, y=2, z=3)
test(x=1, 2, 3) # 报错
- 总结:传参方式方式总共有2种:1.位置传参 2.关键字传参。位置传参与形参一一对应,位置传参需带上形参名,可以不和形参一一对应,位置传参必须在关键字参数之前
参数类型
python函数参数非常复杂,需要理解才能良好的使用
形参默认值(默认参数)
python定义函数时,可以为形参设置默认的值,调用者可以不传入该参数,使用默认值简化函数调用
def add(x=1, y=2):
print(x + y)
def add2(x=2,y): # 定义函数也要遵循位置参数在前,关键字参数在后
print(x+y)
add() # 使用形参默认值x=1,y=2
add(3, 4)
add(y=3, x=4)
add(3, y=5)
add(x=6, 10) # 错误,记住位置参数必须在关键字参数之前
可变位置参数
允许调用方传入0到n个位置参数,在形参前加上*
def add(iterable):
num = 0
for i in iterable:
num += i
print(num)
def add2(*nums):
num = 0
for i in nums:
num += i
print(num)
add([x for x in range(101)])
add2(1, 3, 4, 5, 6)
当形参不加*,传入的参数必须是可迭代的对象,加上*,可以传入任意值,nums会把参数封装成元祖
可变关键字参数
允许调用方传入0到n个关键字参数,在形参前加上**
def test(**kwargs):
for k, v in kwargs.items():
print(k, v)
test(a=1, b=2, c=3)
- 注意:可变位置参数必须在可变关键字参数前面
混合使用
def showConfig(a, b, *args, **kwargs):
pass
def showConfig(a, b=2, *args, **kwargs):
pass
def showConfig(a=2, b, *args,**kwargs): # 错误,位置参数必须在关键字参数之前
pass
def showConfig(a, b, **kwargs, *args): # 错误,可变关键字参数必须在可变位置参数后面
pass
def fn(x, y, *args, **kwargs):
print(x, y, args, kwargs)
fn(1, 2, 3, 4, 5, a=1, b=2)
fn(1, 2)
fn(1, 2, 3)
fn(1, 2, a=1, b=2) # a和b都被kwargs接收
fn(x=1, y=2, z=3) # z被kwargs接收
fn(x=1, y=2, 1, 2) # 位置参数必须在关键字参数前
fn(1, 2, x=3, y=4) # got multiple values for argument 错误
keyword-only参数
python3后增加keyword-only参数,在一个*号或可变位置参数后定义的形参,只能通过关键字参数传参
def fn(*args, a, b):
print(args, a, b)
def fn1(**kwargs, a, b): # 直接语法错误
pass
def fn2(*args, a=1, b=2): # 可以设置默认值
print(args, a, b)
fn(1, 2, 3, a=4, b=4)
fn(a=4, b=4)
fn(1, 2, 3, 4, 5) # 报错:missing 2 required keyword-only arguments: 'a' and 'b'
fn2()
- 如果不需要前面的可变位置参数,可简写成*
def fn3(*, a, b=1):
print(a, b)
fn3(a=3)
positional-only参数
在python3.8后,增加只允许位置传参的参数,在/前的参数都是位置传参
结合所有的参数类型
-
a和b只能通过位置传参的方式传参,a=或b=都将会报错
-
c和d可以通过位置传参或关键字传参
-
e和f只能通过关键字传参
参数解构
使用*或**将可迭代对象结构,将所有的值作为函数的参数
def add(*nums):
num = 0
for i in nums:
num += i
print(num)
def fn(*args):
for i in args:
print(i)
l = [ x for x in range(101) ]
d = {"a": 1, "b":2, "c":3}
add(*d.values())
add(l) # 报错,因为是把整个列表当参数传入
add(*l) # 把l列表的中值当参数传入
fn(*d) # 等于d.keys()
def fn(**kwargs):
for k, v in kwargs.items():
print(k, v)
d = {"a": 1, "b": 2, "c": 3}
fn(**d)