函数的传递方式
- 位置参数
位置参数就是将对应位置的实参赋值给对应位置的形参。
默认值:定义形参的时候,可以给形参指定默认值,如果用户传递了实参,默认值不会发挥任何作用,如果用户没有传递,则采用默认值。
def fn(a,b,c=20): |
执行结果:
a = 1 b = 2 c = 20 |
2、关键字参数
关键字参数可以不按照形参定义的顺序去传递,而根据参数名去传递
def fn(a=5,b=10,c=20): print('a=',a) print('b=', b) print('c=', c) fn(b=1,c=2,a=3) |
执行结果:
a= 3 b= 1 c= 2 |
位置参数和关键字参数可以混合使用,混合使用的时候,必须将位置参数写到关键字参数前面:
def fn(a=5,b=10,c=20): print('a=',a) print('b=', b) print('c=', c) fn(1,c=8) |
执行结果如下:
a= 1 b= 10 c= 8 |
3、实参的类型
实参可以传递任意类型的对象
浅复制:
def fn4(a): a[0] = 50 print('a=',a,id(a)) c =10 c = [1,2,3] fn4(c.copy()) print('c=',c,id(c)) |
执行结果如下:
a= [50, 2, 3] 2303414788808 c= [1, 2, 3] 2303414788744 |
如果你传递的是一个可变对象的时候,而又不希望在函数内部的操作影响到函数外部,那么就可以考虑传递一个副本。
4、不定长参数
在定义函数时,可以在形参前面加一个*,这个形参就可以获取到所有的实参,所有的实参会保存在元组中(封包)
例如求任意数的和:
def fn5(*a): n = 0 for i in a: n += i return n print(fn5(1,3,5,7,9)) |
执行结果如下:
25 |
不定长参数也可以和其他参数配合使用
def fn2(a,b,*c): print('a=',a) print('b=', b) print('c=', c) fn2(1,2,3,4,5) |
执行结果如下:
a= 1 b= 2 c= (3, 4, 5) |
不定长参数不是必须写在最后,但是要注意,带*的参数后面的所有参数,必须以关键字参数形式传递。
不定长关键字参数:
def fn3(**a): print('a = ',a) fn3(b=1,d=2,c=3) |
执行结果如下:
a = {'b': 1, 'd': 2, 'c': 3} |
**形参可以接受其他的关键字参数,它会将这些参数统一保存到一个字典当中。
**形参只能有一个,并且必须写在所有参数后面
def fn3(b,c,**a): print('a = ',a) print('b =',b) print('c =',c) fn3(1,2,f=5,d=6,e=7) |
执行结果如下:
a = {'f': 5, 'd': 6, 'e': 7} b = 1 c = 2 |
5、函数的解包
def fn4(a,b,c): print('a = ',a) print('b = ',b) print('c = ',c) t = (10,20,30) fn4(*t) |
执行结果如下:
a = 10 b = 20 c = 30 |
传递实参,也可以在序列类型的参数添加*,程序会自动将序列当中的元素依次作为参数传递。序列当中的元素个数必须和形参的个数保持一致。
def fn4(a,b,c): print('a = ',a) print('b = ',b) print('c = ',c) t = {'a':1,'b':2,'c':3} fn4(**t) |
执行结果如下:
a = 1 b = 2 c = 3 |
6、函数的返回值
返回值就是函数执行以后返回的结果;return后面可以跟任意的对象,甚至可以是一个函数。
如果仅仅写一个return或者不写return则相当于return None
执行return后代表函数结束。
def fn4(): |
执行结果如下:
0 1 2 |
fn4和fn4()的区别:
print(fn5) 是函数对象,打印的是函数对象
print(fn5())是在调用函数,实际上在打印fn5()函数的返回值
7、文档字符串
Help()可以查询python函数中的用法
语法help(函数对象)
def fn(a:int,b:str,c:bool): |
执行结果如下:
Help on function fn in module __main__:
fn(a: int, b: str, c: bool) 函数的参数 :param a: 作用。。。。 :param b: 作用。。。。 :param c: 作用。。。。 :return: int |
8、函数的作用域
作用域指的是变量生效的区域,在python中有2种作用域
全局作用域:全局作用域在程序执行时创建,在程序结束时销毁,所有函数以外的区域都是全局作用域,在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序中的任意位置访问。
函数作用域:函数作用域在函数调用时创建,在调用结束时销毁,函数每调用一次就会产生一个新函数的作用域,在函数作用域中定义的变量都是局部变量,它只能在函数内部被访问。
def fn2(): |
执行结果如下:
fn3中: a = 40 |
全局变量声明:
a = 20 |
执行结果如下:
函数内部: a = 10 函数外部: a = 10 |
9、命名空间
命名空间实际上就是一个字典,是一个专门用来存储变量的字典
locals()用来获取当前作用域的命名空间
如果在全局作用域中调用locals()函数则获取全局作用域命名空间,如果在函数作用域中调用locals(),则获取函数命名空间
a = 20 |
执行结果如下:
函数内部: a = 10 函数外部: a = 10 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000021279246358>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/MyPython/demo_1.py', '__cached__': None, 'a': 10, 'fn2': <function fn2 at 0x000002127770C1E0>} |
10、递归
递归式函数就是在函数中调用自己。
递归式函数的两个条件:
- 问题可以被分解成最小的问题,当满足基线条件时,递归不再执行了
- 递归条件(将问题继续分解的条件)
求数的阶乘
def fn2(n): |
执行结果如下:
3628800 |