闭包的定义
如果一个函数的内部定义了另一个函数,外部我们叫他外函数,内部我们叫它内函数.如果内函数里运用了外函数的局部变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包.
总结一下闭包的概念
1.内部函数定义在外部函数内部
2.内部函数有使用外部函数的局部变量
3.内部函数作为外部函数的返回值
例如
# 定义一个外部函数
def father():
name = '我是外部函数'
# 定义一个内部函数
def son(var):
print('{}传递{}给内部函数'.format(name, var))
return son
res = father()
res('变量')
结果
我是外部函数传递变量给内部函数
Process finished with exit code 0
内部函数使用了外部函数的局部变量name,这样就构成了一个闭包
闭包的使用
替代类
闭包主要运用在需要将外部函数作用域中的变量绑定到内部函数的场景中,在释放掉外部函数之后内部函数也不会受到影响.所以闭包可以替代简单的类,从而可以减少开销.
例如
# 原版
class Animal(object):
def __init__(self, name):
self.name = name
def say(self, voice):
print('{}的叫声是{}'.format(self.name, voice))
dog = Animal('狗')
dog.say('汪')
# 闭包改良后
def ani(name):
def voi(vo):
print('{}的叫声是{}'.format(name, vo))
return voi
cat = ani("猫")
cat('喵')
装饰器
定义
装饰器就是把原函数加工一下,返回一个新的函数,这个新函数不会改变原函数的功能代码
步骤
1.确定形参为一个函数名
2.在工厂函数内部,定义一个新函数
3.新函数内部添加新功能,调用形参函数,return 调用结果
4.return新函数
例如
def factory(func):
def inner():
print('###################') # 装饰的新功能
return func() # 调用原函数,实现原函数的功能
return inner
def show():
print('我是show')
show = factory(show)
show()
def factory(func):
def inner():
print('###################') # 装饰的新功能
return func() # 调用原函数,实现原函数的功能
return inner
@factory
def show():
print('我是show')
show()
装饰器的应用
注意:
1.在装饰器内部调用原函数时,必须把原函数的执行结果进行 return
2.同一个装饰器是可以被多个函数使用的
def parma_int(old):
def new(num1, num2):
if not (isinstance(num1, int) and isinstance(num2, int)):
print('参数必须为整数')
else:
return old(num1, num2) # 注意,原函数的执行结果,我们必须返回
return new
@parma_int
def my_sum(num1, num2):
return num1 + num2
@parma_int
def my_mul(num1, num2):
return num1 * num2
print(my_sum(1, '李白'))
print(my_mul(3, 5))
装饰器传入参数问题
1.当我们定义装饰器的时候,我们是不知道 使用装饰器的函数的参数数量的
2.我们在装饰器里面调用原函数需要传入参数
3.我们在外面使用函数时,实际调用的是新函数,新函数也需要传参
4.参数数量应该保持一致
注意:
因为要保持参数一致,又不知道使用装饰器的函数需要传入多少参数
解决办法:
不定长参数方式传递
def factory(old):
def new(*args, **kwargs):
print('这里装修')
return old(*args, **kwargs)
return new
@factory
def show(name):
print(name)
show('杜甫')
@factory
def show1(name, age):
print(name, age)
show1('李白', 18)