4. 四、函数
4.1. 定义
函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需要调用其函数名即可。
4.2. 特性
- 减少重复代码
- 使程序变的可扩展
- 使程序易于维护
4.3. 默认参数
定义函数时,给形参赋值,这个值就是默认参数。在调用函数时,如果不填写该参数,表示使用默认参数。定义函数时,默认参数应该在位置参数的后面。
4.4. 形参和实参
顾名思义,形参指形式参数,实参指实际参数。形参是定义函数时,类似于用于占位的参数,它占领的这个位置用于调用时,给实参放进程序里用。
4.5. 位置参数和关键参数
定义函数时候,理论上可以有无限多个参数。默认情况下,这些参数按0~x从左往右编号,每个位置上的参数都有一个编号,这种通过编号确定位置的参数叫做位置参数
。因此,调用函数时,每个位置的参数是有序的。如果调用时,想随意放置参数,就需要使用关键参数
。
因为调用函数时,用类似于字典中键值对映射关系那种方法制定了对应形参的实参,因此程序不会出错。
del fuc1(name, age, sex, countyr = 'CN'):
return name, age, country, sex
fuc1('Alex', sex = 'man', age = 28)
在上述代码中,name
、age
、sex
是位置参数,三者之间从左往右一次排序,在调用时,三个实参依次表示name、age、sex。比如fuc1('Alex', 21, 'man')
如果使用关键参数,比如第二个参数写sex = 'man'
,程序输出时,依然会按照name、age、country和sex的顺序输出。
4.6. 可变参数
定义函数时,在参数前面加一个*
,表示这个参数为可变参数。可变参数,顾名思义,这个参数代表的参数个数是可变的。事实上,函数是将这些所有参数打包成一个元祖传给带星的这个参数。
那么问题来了,我们也可以自己打包成一个列表或者元祖传给可变参数。但是要注意,如果仅仅是写一个列表或者元祖,可变参数会将这个列表或者元祖整体作为一个参数。因此,我们自行打包时,需要加一个*
,表示我们将列表或者元祖中的元素打包后传给可变参数。
del fuc1(course, *name)
reture course, name
fuc1('Python3', 'Alex', 'shanshan', 'black girl') # 'Alex'到'black girl'都是可变参数中的元素。
fuc1('Python3', *['Alex', 'shanshan', 'black girl']) # 自行打包可变参数
因为可变参数的参数可数是不固定的,因此在调用函数时需要注意撰写其后面的参数时需要使用关键参数
的形式。
del fuc1(course, *name, age)
print('课程为:', course, *name, age)
fuc1('Python3', 'Alex', 21) # 这种写法会报错,因为Python会错误的将`'Alex'`和`21`当成可变参数,因此缺少一个参数`age`。正确的写法应该是:
fuc1('Python3', 'Alex', age = 21)
一个*
表示元祖,两个**
表示字典。用于添加未定义的参数。
del fuc1(name, *args, **kwargs)
print(name, args, kwargs) # 注意,这里打印参数时,不需要添加`*`
fuc1('Alex', 21, '51w', age = 21, school = 'luffy')
4.7. 局部变量和全局变量
函数中局部变量的作用域只在函数内,函数外的全局变量作用域在整个程序内。因此函数外不能使用函数内的变量,但是函数内可以使用函数外的变量,但是不能修改函数外的变量。否则Python会自动在函数内生成一个与要修改的全局函数变量相同变量名的局部变量。如果确实像在函数内修改全局变量,需要在函数内对需要修改的全局变量进行生命golbal 函数变量名
。
4.8. 内嵌函数和闭包
函数支持嵌套。即定义函数时,在定义的函数内部可以再定义函数。比如:
del fuc1():
print('调用第一个函数')
del fuc2():
print('调用第二个函数')
fuc2()
因为函数fuc2
是在fuc1
中定义的,因此,在函数fuc1
中可以任意调用函数fuc2
,而在函数fuc1
外,则不能调用函数fuc2
。
4.9. 返回值
在定义函数是,凡是执行语句return
,其后面的所有语句将不再执行。