携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
一、函数的参数引用
1、在Python中函数参数是传递引用,也就是数据的内存地址。 2、对于不可变类型,修改形参,不影响实参。 3、对于可变类型来说,修改形参,会影响实参。
1.1、不可变类型
不可变类型,例如:
n = 8
def add_num(n):
n += 3
print('add_num函数中的n:', n)
add_num(n)
print('全局变量的n:', n)
效果:
1.2、可变类型
可变类型,例如:
arr = [9, 8, 7]
def show_list(arr):
if isinstance(arr, list):
arr.insert(0, 10)
print('show_list函数中的arr:', arr)
show_list(arr)
print('全局变量的arr:', arr)
效果:
二、函数闭包
python中函数是一段可以执行的代码,编译完就固定了,每个定义的函数在内存中只有一个实例,运行这个函数就可以执行这个函数,函数也可嵌套定义,就是在函数中可以定义另一个函数,这种嵌套的写法,就会产生闭包问题。
2.1、嵌套函数
def outer():
a = 101
def inner():
b = 202
# b += a # 内部函数可以使用外部函数的变量,但是不能修改
nonlocal a # 内部函数引用外部函数加nonlocal
a += b
print('内部函数b:', b)
print('外部函数a:', a)
print('外部函数a(未改变前):', a) # 先执行打印a
inner() # 后执行改变a
outer()
效果:
2.2、闭包
符合以下3条的场景称为闭包:
1、嵌套函数 2、内部函数引用了外部函数的变量 3、返回值是内部函数
例如:
def outer(n):
a = 101
def inner():
b = a + n
return b
return inner
print(outer(202)())
效果:
三、装饰器
写代码要遵循开放封闭
原则,虽然这个原则是针对面向对象开发,但是适用于函数式编程,规定已经实现的功能代码不允许被修改,但可以被扩展。
装饰器就遵循开放封闭
的原则,在不改变原函数的情况下,扩展了函数的功能。
定义装饰器遵循闭包的原则。
例:
def decorators(func):
print('start')
def inner():
func()
print('铺地板')
print('刷墙')
print('end')
return inner
@decorators
def house():
print('草丕房')
house()
@decorators
就是装饰器,它等同于 @decorators = decorators(house)
。做到了不影响原函数的同时丰富原函数。效果:
装饰器的功能应用场景:
1、引入日志 2、函数执行时间统计 3、执行函数前预备处理 4、执行函数后清理功能 5、权限校验等场景 6、缓存
3.1、带参数的装饰器
def decorators(func):
def inner(htype):
func(htype)
print('铺地板')
print('刷墙')
return inner
@decorators
def house(htype):
print('我的房子类型是{}'.format(htype))
house('四合院')
效果:
如果原函数有参数的话,那么装饰器里内部函数也要带参。
在正常开发中,我们写一个装饰器一定要适配多种场景,例如无参,多个参数,关键字参数的场景,例:
def decorators(func):
def inner(*args, **keywords):
func(*args, **keywords)
print('我们生存在地球')
print('我们要爱护环境')
return inner
@decorators
def human():
print('我们是人类')
human()
print('----------------')
@decorators
def bird(atype, canfly):
print('我是{},我{}'.format(atype, canfly))
bird('鸽子', '会飞')
print('----------------')
@decorators
def animal(atype, canfly, leg=4):
print('我是{},我{},我有{}条腿'.format(atype, canfly, leg))
animal('狮子', canfly='不会飞')
效果:
3.2、装饰器修饰有返回值函数
原函数带有返回值,装饰器中也带有返回值:
def decorators(func):
def inner(*args, **keywords):
r = func(*args, **keywords)
print('我们生存在地球')
print('我们要爱护环境')
return r
return inner
@decorators
def animal(atype, canfly, leg=4):
print('我是{},我{},我有{}条腿'.format(atype, canfly, leg))
return '狮子王'
r = animal('狮子', canfly='不会飞')
print(r)
效果:
如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持