定义函数的规则如下:
-
函数代码块以 def 关键词开头。
-
后接函数名称和圆括号
()
。 -
圆括号中可以使用参数。
-
函数内容以冒号起始,并且缩进。
-
return 结束函数,可以选择性地返回一个值。不带 return 相当于返回 None。
函数样式:
def 函数名(形式参数):
函数体
return 返回值
例一:
默认函数的参数是按照位置顺序传递的。
注意:函数要运行分两步:
1、定义函数
2、调用函数(如果有参数,要传入参数)
1 # 定义函数。其中a,b为形式参数 2 def f(a, b): 3 c = a*2 - b 4 return c 5 6 7 # 调用函数,其中3,5为实际参数 8 # 调用函数的时候,3对应形式参数的a,5对应形式参数的b 9 result = f(3, 5) 10 print(result)
运行结果:
1 "D:\Program Files (x86)\python\python.exe" E:/python/python爬虫/从0开始、/a7.py 2 1 3 4 Process finished with exit code 0
-
实际参数:简称实参,我们刚才在调用函数的时候传入 3 和 6 就是实参。主要体现在实际执行函数的时候使用。
-
形式参数:简称形参,我们刚才在定义函数的时候
add(a, b)
中的 a 和 b 就是形参。主要体现在它只是一个形式和格式,真正要执行的时候还是要看传入的实参。
整个函数调用就是将实参传递给形参,完成计算后返回,并且打印返回值。
例二:
函数的参数可以按照赋值传递
1 # 定义函数。其中a,b为形式参数 2 def f(a, b): 3 c = a*2 - b 4 return c 5 6 7 # 调用函数,其中3,5为实际参数 8 # 按照赋值传递参数 9 result = f(b=3, a=5) 10 print(result)
运行结果:
1 "D:\Program Files (x86)\python\python.exe" E:/python/python爬虫/从0开始、/a7.py 2 7 3 4 Process finished with exit code 0
result = f(b=3, a=5)中,b=3, a=5为关键字参数
可变参数
例一:以元组的形式输出
1 # 在参数 b 前面加一个 * ,表示这个参数是可变长度参数,当前面的参数都赋值结束后,剩下的参数顺次给这个参数赋值。 2 def print_num(a, b, *c): 3 print(a, b, c) 4 5 6 # 调用函数,其中1赋值给a,2的值赋值给b,3,4,5全部复制给了c,其中3,4,5以元组的形式输出打印 7 print_num(1, 2, 3, 4, 5)
运行结果:
1 "D:\Program Files (x86)\python\python.exe" E:/python/python爬虫/从0开始、/a8.py 2 1 2 (3, 4, 5) 3 4 Process finished with exit code 0
例二:
1 # *a表示a是一个可变长度的参数,传入的参数依次给a赋值,并将a的值以元组的形式打印出来 2 def print_num(*a): 3 print(a) 4 5 6 # 传入多个参数,依次给a赋值 7 print_num(1, 2, 3, 4, 5) 8 # 使用列表的形式,当做一个参数传递 9 print_num([2, 3, 4, 5]) 10 # 使用元组的形式,当做一个参数传递 11 print_num((2, 3, 4, 5, 6)) 12 # 当传入列表形式,并且列表前面有*的情况下,当做多个值依次传递给a 13 print_num(*[2, 3, 4, 5, 6])
运行结果:(注意:输出的结果均为元组类型)
1 "D:\Program Files (x86)\python\python.exe" E:/python/python爬虫/从0开始、/a9.py 2 (1, 2, 3, 4, 5) 3 ([2, 3, 4, 5],) 4 ((2, 3, 4, 5, 6),) 5 (2, 3, 4, 5, 6) 6 7 Process finished with exit code 0
我们传进的所有参数都会被a变量收集,它会根据传进参数的位置合并为一个元组(tuple),a是元组类型,这就是包裹位置传递
例二:以字典的形式输出
我们还可以给这个参数前面加两个 * ,表示这个参数可以传递的数据类型是以字典的形式传递的
a是一个字典(dict),收集所有关键字参数
1 # **a表示a是一个可变长度的参数,表示这个参数可以传递的数据类型是以字典的形式传递的 2 def print_num(f, **a): 3 print(f, a) 4 5 6 # 调用函数,根据位置,55赋值给了f,后面的赋值给了**a,并且以字典的形式输出 7 print_num(55, a=1, b=2, c=3, d=4) 8 # 字典前加**,字典中每对键值对做为一个关键字参数传递给函数 9 print_num(66, **{'a': 1, 'b': 2, 'c': 3, 'd': 4})
运行结果:
1 "D:\Program Files (x86)\python\python.exe" E:/python/python爬虫/从0开始、/a10.py 2 55 {'a': 1, 'b': 2, 'c': 3, 'd': 4} 3 66 {'a': 1, 'b': 2, 'c': 3, 'd': 4} 4 5 Process finished with exit code 0
例三:两种可变参数的区别
1 def different(*a, **k): 2 print('a = ', a) 3 print('k = ', k) 4 print('```'*10) 5 6 7 different(1, 2, 3, 4) 8 different(b=2, c=3, d=4) 9 different(1, 2, 3, 4, b=2, c=3, d=4) 10 different('a', 1, None, b=2, c='3', d=4)
运行结果:
1 "D:\Program Files (x86)\python\python.exe" E:/python/python爬虫/从0开始、/a11.py 2 a = (1, 2, 3, 4) 3 k = {} 4 `````````````````````````````` 5 a = () 6 k = {'b': 2, 'c': 3, 'd': 4} 7 `````````````````````````````` 8 a = (1, 2, 3, 4) 9 k = {'b': 2, 'c': 3, 'd': 4} 10 `````````````````````````````` 11 a = ('a', 1, None) 12 k = {'b': 2, 'c': '3', 'd': 4} 13 `````````````````````````````` 14 15 Process finished with exit code 0
可以看到,这两个是Python中的可变参数。*args 表示任何多个无名参数,它是一个tuple;**kwargs 表示关键字参数,它是一个dict。
并且同时使用*args和**kwargs时,必须*args参数列要在**kwargs前,像different(a=1, b='2', c=3, a', 1)这样调用的话,会提示语法错误SyntaxError: positional argument follows keyword argument
出现这个bug的原因在于参数位置不正确,关键字参数
必须跟随在位置参数
后面! 因为python函数
在解析参数时, 是按照顺序来的, 位置参数
是必须先满足, 才能考虑其他可变参数。
例四:注意各种参数的位置
1 def abc(a, b=3, *c, **d): 2 print(a) 3 print(b) 4 print(c) 5 print(d) 6 7 8 abc(4, 5, 6, 7, x=55, y=66)
运行结果:
1 "D:\Program Files (x86)\python\python.exe" E:/python/python爬虫/从0开始、/a12.py 2 4 3 5 4 (6, 7) 5 {'x': 55, 'y': 66} 6 7 Process finished with exit code 0
注意:各种参数的位置不能错,默认参数b必须放在*c之前,*c必须放在**d之前,调用函数的时候,实际参数修正形式参数的值,所以b的输出结果为5
1、位置参数:
调用函数时所传参数的位置必须与定义函数时参数的位置相同,且有多种类型的参数定义和调用函数时,位置参数应该放在最前面
2、关键字参数(函数调用的时候指定):
使用关键字参数会指定参数值赋给哪个形参,调用时所传参数的位置可以任意
3、可变参数:
*位置参数:可接受任意数量的位置参数(元组);只能作为最后一个位置参数出现,其后参数均为关键字参数
**关键字参数:可接受任意数量的关键字参数(字典);只能作为最后一个参数出现
4、默认参数(函数定义的时候指定,本例中b=3为默认参数):
默认参数的赋值只会在函数定义的时候绑定一次。
默认的形式参数可以不传递实际参数。
如果想改变形式参数的默认值,那么正常的传递一个实际参数就行了,本例中给默认参数b=3又传递了实际参数5改变了默认参数b的值。
————————————————