函数
参数
- 形参 、实参、默认参数、关键参数
def a(x,y,z='默认参数',*args)
...
return x,y
a(2,z=1,y=3) # 这里的z=和y=为关键参数
- 非固定参数:
方式一:如果参数中出现*号,传递的参数就可以不再是固定参数,传过来的所有参数打包为元组
def register(name,age,*args):
print(name,age,args)
register('q1ang')
register('q1ang',22)
register('q1ang',22,'CN')
register('q1ang',22,'CN','xxx')
方式二:当希望传递的参数为['q1ang',22,'CN','xxx']
register('q1ang',*['q1ang',22,'CN','xxx']) # 这样的传递效果和*args一样
方式三:参数中出现**号,接收未定义的关键字参数传过来的所有参数打包为字典
def register(name,age,*args,**kwargs):
print(name,age,args,kwargs)
register('q1ang',22,)
>>>q1ang 22 () {}
register('q1ang',22,'china','boy')
>>>q1ang 22 ('china', 'boy') {}
register('q1ang',22,'china','boy',province='Ningxia')
>>>q1ang 22 ('china', 'boy') {'province': 'Ningxia'}
返回值
要想获取函数的执行结果,就可以用return语句把结果返回
局部变量、全局变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用
name = 'q1ang'
def change_name(name):
print("before change:", name)
name = 'Q1ANG'
print("after change", name)
change_name(name)
print(name)
before change: q1ang
after change Q1ANG
q1ang
如果需要在函数内修改全局变量:
global name
name = 'xxx' # 修改需要在定义全局变量下边,不建议在函数内修改全局变量
在函数里修改列表数据:
names = ['q1ang',22]
def change_name():
names = ['Q1ANG',22] # 这样不能修改,这里相当于修改了列表的内存地址
names[0] = 'Q1ANG'
change_name()
print(names)
>>> ['Q1ANG',22]
嵌套函数
def func1():
print('func1')
def func2():
print('func2')
作用域
函数就是一个作用域,局部变量其实是放在其作用域中
age = 18
def func1():
age = 73
print('q1ang')
def func2():
age = 26
pring('Q1ANG')
匿名函数
节省代码量、外观简洁
def calc(x,y):
return x*y
lambda x,y:x*y # 声明一个匿名函数
lambda x,y:x*y if x < y else x/y
func = lambda x,y:x*y
print(func(2,6))
高阶函数
变量可以指定一个函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def func(x):
print(x)
def func1():
return 2
def func2(): # return 另一个函数
return func1
func(func1())
func2()
递归函数
在函数执行的过程中调用自己。
特点
- 必须有一个明确的结束条件,要不就会变成死循环了,最终撑爆系统
- 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
- 递归执行效率不高,递归层次过多会导致栈溢出
应用
阶乘
def func(n):
if n == 1:
return 1
return n * func(n-1)
print(func(10))
二分法
尾递归
def func(n):
return func(n+1)