一 函数的返回值
关键字:return
def home():
print(123)
return # 代码走到这立刻结束
print('hello')
return 1, 2, 3 # (1, 2, 3)
1. 每一个函数不行必须要有返回值的,可有可无
2. 当函数中没有return关键字,那么,函数的返回结果是什么?None
3. 只有是return关键字后面的数据才是函数的返回结果
4. 一个函数中只能有一个return关键字,函数体体代码只有遇到return直接退出
5. return后面可以返回值多个值,逗号隔开,以元组的形式返回
res = home() # 把home函数执行之后返回的结构赋值给res变量
print(res) # None (1, 2, 3)
print(res[0]) # None (1, 2, 3)
print(res[1]) # None (1, 2, 3)
print(res[2]) # None (1, 2, 3)
二 函数参数的两大分类(形参、实参)
函数的参数分为形式参数和实际参数,简称形参和实参:
形参即在定义函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值。
实参即在调用函数时,括号内传入的值,值可以是常量、变量、表达式或三者的组合:
# 1:实参是常量
res=my_min(1,2)
# 2:实参是变量
a=1
b=2
res=my_min(a,b)
# 3:实参是表达式
res=my_min(10*2,10*my_min(3,4))
# 4:实参可以是常量、变量、表达式的任意组合
a=2
my_min(1,a,10*my_min(3,4))
在调用有参函数时,实参(值)会赋值给形参(变量名)。在Python中,变量名与值只是单纯的绑定关系,而对于函数来说,这种绑定关系只在函数调用时生效,在调用结束后解除。
2.1 位置参数
位置即顺序,位置参数指的是按顺序定义的参数,需要从两个角度去看:
1.在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参,凡是按照这种形式定义的形参都必须被传值
def register(name,age,sex): #定义位置形参:name,age,sex,三者都必须被传值
print('Name:%s Age:%s Sex:%s' %(name,age,sex))
register() #TypeError:缺少3个位置参数
2.在调用函数时,按照从左到右的顺序依次定义实参,称为位置实参,凡是按照这种形式定义的实参会按照从左到右的顺序与形参一一对应
register('lili',18,'male') #对应关系为:name=’lili’,age=18,sex=’male’
Name:lili Age:18 Sex:male
2.2 关键字参数
在调用函数时,实参可以是key=value的形式,称为关键字参数,凡是按照这种形式定义的实参,可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值
register(sex='male',name='lili',age=18)
Name:lili Age:18 Sex:male
需要注意在调用函数时,实参也可以是按位置或按关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值
register('lili',sex='male',age=18) #正确使用
register(name='lili',18,sex='male') #SyntaxError:关键字参数name=‘lili’在位置参数18之前
register('lili',sex='male',age=18,name='jack') #TypeError:形参name被重复赋值
debug模式(了解)
1. 先打断点,在代码的左侧点一下鼠标的左键,会出现一个红点
2. 右键选择debug选项
2.3 默认参数
在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数。例如编写一个注册学生信息的函数,如果大多数学生的性别都为男,那完全可以将形参sex定义成默认参数
def register(name,age,sex='male'): #默认sex的值为male
print('Name:%s Age:%s Sex:%s' %(name,age,sex))
定义时就已经为参数sex赋值,意味着调用时可以不对sex赋值,这降低了函数调用的复杂度
register('tom',17) #大多数情况,无需为sex传值,默认为male
Name:tom Age:17 Sex:male
register('Lili',18,'female') #少数情况,可以为sex传值female
Name:Lili Age:18 Sex:female
'''当默认值是列表的时候,哪么,当多次被调用的时候,多个值会指向同一个固定的地址'''
def func(name, age, gender, hobby=[]):
hobby.append(gender)
print(hobby)
print("name:%s, age:%s, gender:%s, hobby:%s" % (name, age, gender, hobby))
func('jerry', 18, 'male')
func('tank', 18, 'female')
func('tank1', 18, 'male')
1. 函数在定义阶段,给的默认值直接就定死了,后续不会在改变
2. 根据变量名和变量值在内存中得关系来理解
2.4 可变长度的参数
参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,实参的定义无非是按位置或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数
2.4.1 可变长度的位置参数
如果在最后一个形参名前加*号,那么在调用函数时,溢出的位置实参,都会被接收,以元组的形式保存下来赋值给该形参
def foo(x,y,z=1,*args): #在最后一个形参名args前加*号
print(x)
print(y)
print(z)
print(args)
foo(1,2,3,4,5,6,7) #实参1、2、3按位置为形参x、y、z赋值,多余的位置实参4、5、6、7都被*接收,以元组的形式保存下来,赋值给args,即args=(4, 5, 6,7)
1
2
3
(4, 5, 6, 7)
如果我们事先生成了一个列表,仍然是可以传值给*args的
def foo(x,y,*args):
print(x)
print(y)
print(args)
L=[3,4,5]
foo(1,2,*L) # *L就相当于位置参数3,4,5, foo(1,2,*L)就等同于foo(1,2,3,4,5)
1
2
(3, 4, 5)
注意:如果在传入L时没有加*,那L就只是一个普通的位置参数了
foo(1,2,L) #仅多出一个位置实参L
1
2
([1, 2, 3],)
如果形参为常规的参数(位置或默认),实参仍可以是*的形式
def foo(x,y,z=3):
print(x)
print(y)
print(z)
foo(*[1,2]) #等同于foo(1,2)
1
2
3
如果我们想要求多个值的和,*args就派上用场了
def add(*args):
res=0
for i in args:
res+=i
return res
add(1,2,3,4,5)
15
2.4.2 可变长度的关键字参数
如果在最后一个形参名前加**号,那么在调用函数时,溢出的关键字参数,都会被接收,以字典的形式保存下来赋值给该形参
def foo(x,**kwargs): #在最后一个参数kwargs前加**
print(x)
print(kwargs)
foo(y=2,x=1,z=3) #溢出的关键字实参y=2,z=3都被**接收,以字典的形式保存下来,赋值给kwargs
1
{'z': 3, 'y': 2}
如果我们事先生成了一个字典,仍然是可以传值给**kwargs的
def foo(x,y,**kwargs):
print(x)
print(y)
print(kwargs)
dic={'a':1,'b':2}
foo(1,2,**dic) #**dic就相当于关键字参数a=1,b=2,foo(1,2,**dic)等同foo(1,2,a=1,b=2)
1
2
{'a': 1, 'b': 2}
注意:如果在传入dic时没有加**,那dic就只是一个普通的位置参数了
foo(1,2,dic) #TypeError:函数foo只需要2个位置参数,但是传了3个
如果形参为常规参数(位置或默认),实参仍可以是**的形式
def foo(x,y,z=3):
print(x)
print(y)
print(z)
foo(**{'x':1,'y':2}) #等同于foo(y=2,x=1)
1
2
3
如果我们要编写一个用户认证的函数,起初可能只基于用户名密码的验证就可以了,可以使用**kwargs为日后的扩展供良好的环境,同时保持了函数的简洁性。
def auth(user,password,**kwargs):
pass
2.5 命名关键字参数
命名关键字传参:在形参中会出现*的用法,如果出现在*号后面的形参,那么,实参传递的时候,必须以关键字的形式传递
def register(name,age,*,sex,height,salary): #sex,height为命名关键字参数
pass
register('kevin', 10, 'male', 1.9)
register('kevin', 10, sex='male', height=1.9, salary=2000)
2.6 组合使用
综上所述所有参数可任意组合使用,但定义顺序必须是:位置参数、默认参数、*args、命名关键字参数、**kwargs可变参数*args与关键字参数**kwargs通常是组合在一起使用的,如果一个函数的形参为args与kwargs,那么代表该函数可以接收任何形式、任意长度的参数
def wrapper(*args,**kwargs):
pass
提示: *args、**kwargs中的args和kwargs被替换成其他名字并无语法错误,但使用args、kwargs是约定俗成的。