函数的定义
函数是Python里面组织代码的最小单元
def add(x, y):
函数定义是使用def关键字来定义的,仅接着是函数名,函数名后面用一对小括号列出参数列表,
参数列表侯曼使用冒号结束函数体,参数可有可无,不影响函数的定义
print(x + y)
函数体是正常的Python语句,可以包含任何结构
return x + y
return 语句表示函数的返回值
函数是由输入(参数)和输出(返回值),函数其实是一个代码单元,把输入转化为输出
函数的调用
定义函数的时候,并不会执行函数体,当调用函数的时候,才会执行其中的语句块
调用函数,是直接使用函数的名字来调用
>>> def add(x, y): 定义一个函数
... print(x + y) 函数体是打印参数x加上参数y等于多少
... return x + y 函数的返回值
...
>>> add(3,5) 使用名称直接调用函数,将参数3和5分别传给x和y
8 函数体的值
8 函数的返回值
函数的返回值,在Python的解释器中,是可以直接返回的,但是在我们写到程序中的时候,函数的返回值是需要使用一个变量来接收的
参数是按照顺序的方式传入的,这样的传参方法是位置参数
>>> def add(x, y):
... ret = x + y
... print('{} + {} = {}'.format(x,y,ret))
... return ret
...
>>> add(3,5)
3 + 5 = 8
8
指定关键字来传递参数,这样的传参方法是关键字参数,关键字参数是和顺序无关的
>>> def add(x, y):
... ret = x + y
... print('{} + {} = {}'.format(x,y,ret))
... return ret
...
>>> add(x=3,y=5) 给定指定的关键字
3 + 5 = 8
8
关键字参数和位置参数是可以混合使用的
>>> def add(x, y):
... ret = x + y
... print('{} + {} = {}'.format(x,y,ret))
... return ret
...
>>> add(3,y=5) 同时存在位置参数和关键字参数
3 + 5 = 8
8
>>> add(x=3,5) 当位置参数和关键字参数混合使用的时候,位置参数必须在前面,否则会抛出语法错误
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> add(x=3,'5') 根据实际的情况来传入参数,上面的函数体是加法,因此函数只能是整型和浮点类型,或者是字符串类型
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> add('3','5')
3 + 5 = 35
'35'
函数的参数
参数默认值
>>> def inc(base,x=1): 给第二个参数设置一个默认值,若是不传递参数,则使用默认的参数值,若是传递参数,则使用传递的参数值
... return base + x
...
>>> inc(1)
2
>>> inc(1,2)
3
>>> def inc(x=1,y): 带有参数默认值的参数,必须在不带有参数默认值的参数后面
... return x + y
...
File "<stdin>", line 1
SyntaxError: non-default argument follows default argument
参数默认值和关键字参数一起使用,会让代码非常简洁
可变参数
>>> def sum(*lst): 参数前面加一个星号,表示这个参数是可变的,也就是说可以接受多个参数,将这些参数构成一个元组,只能通过为止参数传参
... ret = 0
... for x in lst:
... ret += x
... return ret
...
>>> sum(1,2,3)
6
>>> def connect(**kwargs): 参数前加两个星号,表示这个参数是可变的,可以接受任意多个参数,这些参数构成一个字典,此时只能同时关键字参数传参
... for k,v in kwargs.items():
... print('{} -> {}'.format(k,v))
...
>>> connect(host='127.0.0.1', post=3306)
host -> 127.0.0.1
post -> 3306
>>> def fn(*args, **kwargs): 两种可变参数是可以一起使用的时候,位置可变参数一定要在关键字可变参数的前面
... print(args)
... print(kwargs)
...
>>> fn(1,2,3,4,a=4,b=5)
(1, 2, 3, 4)
{'a': 4, 'b': 5}
>>> def fn(x,y,*args,**kwargs): 可变参数是可以和普通参数一起使用的
... print(x)
... print(y)
... print(args)
... print(kwargs)
...
>>> fn(1,2,3,4,5,a='a')
1
2
(3, 4, 5)
{'a': 'a'}
>>> def fn(x,y,*args,**kwargs):
... print(x)
... print(y)
... print(args)
... print(kwargs)
...
>>> fn(1,2,3,4,5,x='x') 普通参数和可变参数一起使用的时候,传参的时候必须匹配,是不能出现相同参数名称的情况的
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fn() got multiple values for argument 'x'
>>> def fn(*args, x):
... print(args)
... print(x)
...
>>> fn(1,2,3,x='b') 位置可变参数可以在普通参数之前,但是在位置可变参数之后的普通参数变成keyword-only参数
(1, 2, 3)
b
>>> def fn(**kwargs, x): 关键字参数是不能在普通参数之前的
File "<stdin>", line 1
def fn(**kwargs, x):
^
SyntaxError: invalid syntax
可变参数有两种形式:
- 位置可变参数 : 参数前加一个星号,参数构成一个元组,参数只能以 位置参数 的形式传参
- 关键字可变参数 : 参数前加两个星号,参数构成一个字典,参数只能以 关键字参数 的形式传参
当默认参数和可变参数一起出现的时候,默认参数相当于普通参数
通常来说:
- 默认参数靠后
- 可变参数靠后
- 默认参数和可变参数不同时出现
keyword-only: 必须以Key->Value对的形式出现的,叫做keyword-only
参数解构
>>> def add(x, y):
... ret = x + y
... print('{} + {} = {}'.format(x ,y ,ret))
... return ret
...
>>> lst = [1,2]
>>> add(*lst) 当一个迭代对象需要穿给一个函数当参数的时候,就可以前面加一个星号,把迭代对象解构成位置参数
1 + 2 = 3
3
>>> dit = {'x':1,'y':2}
>>> add(**dit) 将一个keyword-only类型的数据传给一个函数当参数的时候,前面加上两个星号,可以把字典结构成关键字参数
1 + 2 = 3
3
参数的解构发生在函数调用时,可变参数发生在函数定义的时候
可变参数和参数解构并不冲突
参数解构的两种形式
- 一个星号解构的对象:可迭代对象,解构结果是 位置参数
- 两个星号解构的对象:字典,解构的结果是 关键字参数
参数解构的限制
>>> add(**{1:1}) 通过报错可以看出,当使用参数解构的时候,关键字参数的key必须是strings
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() keywords must be strings
函数参数中的keyword-only参数
keyword-only参数是Python3才有的,Python2是没有keyword-only参数的
keyword-only参数的星号是不接受任何值的
>>> def fn(*,x): 星号之后的参数只能通过关键字参数传递,叫做keyword-only参数
... print(x)
...
>>> fn(x=1)
1
>>> fn(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fn() takes 0 positional arguments but 1 was given
>>> fn(1,2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fn() takes 0 positional arguments but 2 were given
keyword-only参数和普通参数结合使用
>>> def fn(x,*,y):
... print(x)
... print(y)
...
>>> fn(1,y=2) 星号后面的必须是key->value的数据类型
1
2
keyword-only参数和默认参数使用
>>> def fn(*,x=1,y=5): keyword-only参数可以有默认值
... print(x)
... print(y)
...
>>> fn()
1
5
>>> def fn(x=1,*,y): keyword-only参数可以和默认值一起出现,不管有没有默认值,不管默认值是不是keyword-only参数
... print(x)
... print(y)
...
>>> fn(y=2)
1
2
通常的用法,keyword-only参数都有默认值