函数的传递方式
- 位置参数
位置参数就是将对应位置的实参赋值给对应位置的形参。
默认值:定义形参的时候,可以给形参指定默认值,如果用户传递了实参,默认值不会发挥任何作用,如果用户没有传递,则采用默认值。
def fn(a,b,c=20):
print('a = ',a)
print('b = ', b)
print('c = ', c)
fn(1,2)
|
执行结果:
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)
|
执行结果:
位置参数和关键字参数可以混合使用,混合使用的时候,必须将位置参数写到关键字参数前面:
def fn(a=5,b=10,c=20):
print('a=',a)
print('b=', b)
print('c=', c)
fn(1,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))
|
执行结果如下:
不定长参数也可以和其他参数配合使用
def fn2(a,b,*c):
print('a=',a)
print('b=', b)
print('c=', c)
fn2(1,2,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)
|
执行结果如下:
传递实参,也可以在序列类型的参数添加*,程序会自动将序列当中的元素依次作为参数传递。序列当中的元素个数必须和形参的个数保持一致。
def fn4(a,b,c):
print('a = ',a)
print('b = ',b)
print('c = ',c)
t = {'a':1,'b':2,'c':3}
fn4(**t)
|
执行结果如下:
6、函数的返回值
返回值就是函数执行以后返回的结果;return后面可以跟任意的对象,甚至可以是一个函数。
如果仅仅写一个return或者不写return则相当于return None
执行return后代表函数结束。
def fn4():
for i in range(5):
if i == 3:
return
print(i)
print('循环结束')
fn4()
|
执行结果如下:
fn4和fn4()的区别:
print(fn5) 是函数对象,打印的是函数对象
print(fn5())是在调用函数,实际上在打印fn5()函数的返回值
7、文档字符串
Help()可以查询python函数中的用法
语法help(函数对象)
def fn(a:int,b:str,c:bool):
"""
函数的参数
:param a: 作用。。。。
:param b: 作用。。。。
:param c: 作用。。。。
:return: int
"""
return 10
help(fn)
|
执行结果如下:
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():
a = 30
def fn3():
a = 40
print('fn3中:','a =',a)
fn3()
fn2()
|
执行结果如下:
全局变量声明:
a = 20
def fn2():
global a
a = 10
print('函数内部:','a =',a)
fn2()
print('函数外部:','a =',a)
|
执行结果如下:
函数内部: a = 10
函数外部: a = 10
|
9、命名空间
命名空间实际上就是一个字典,是一个专门用来存储变量的字典
locals()用来获取当前作用域的命名空间
如果在全局作用域中调用locals()函数则获取全局作用域命名空间,如果在函数作用域中调用locals(),则获取函数命名空间
a = 20
def fn2():
global a
a = 10
print('函数内部:','a =',a)
fn2()
print('函数外部:','a =',a)
print(locals())
|
执行结果如下:
函数内部: 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):
#基线条件
if n ==1:
return 1
#递归条件
return n * fn2(n-1)
print(fn2(10))
|
执行结果如下: