其实装饰器它就是一个闭包。装饰器实现的是,返回一个内嵌的函数以及函数所需要的外部变量,给函数增加特定的功能。
什么是闭包?(https://www.bilibili.com/video/av49346682)
如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包。
闭包例子:
def outer(name):
def inner():
print(name)
return inner # 返回一个inner函数对象,其实不加括号的函数inner就是一个地址
res = outer('python')
res()
装饰器:
使用装饰函数在函数执行前和执行后分别附加额外功能:
def deco(func):
print("before myfunc() called.")
func()
print("after myfunc() called.")
return func
def myfunc():
print("myfunc() called.")
a = deco(myfunc)
a()
使用语法@来装饰函数:
def deco(func):
print("before myfunc() called.")
func()
print("after myfunc() called.")
return func
@deco # @deco的作用就相当于执行deco(myfunc)
def myfunc():
print("myfunc() called.")
myfunc()
装饰器的实现:
使用内嵌函数(闭包)来确保每次新函数(myfunc函数)执行的时候,装饰器(deco函数)的功能都会被调用:
装饰器的作用就是:在执行myfunc函数的时候,都会执行装饰器(deco函数)里边的功能
def deco(func):
def _deco():
print("before myfunc() called.")
func()
print("after myfunc() called.")
return _deco
@deco # @deco的作用就相当于执行myfunc = deco(myfunc)
def myfunc():
print("myfunc() called.")
myfunc()
'''
myfunc = deco(myfunc)干了啥呢?
1.调用deco(myfunc)
2.返回闭包:_deco+外部变量myfunc
3.闭包赋值给myfunc
4.提醒myfunc变成了闭包函数对象
'''
对带参数函数进行装饰:
def deco(func):
def _deco(a, b):
print("before myfunc() called.")
ret = func(a, b)
print("after myfunc() called. result: %s"%(ret))
return ret
return _deco
@deco # @deco的作用就相当于执行myfunc = deco(myfunc)
def myfunc(a, b):
print("myfunc(%s, %s) called."%(a, b))
return a + b
myfunc(1, 2)
myfunc(3, 4)
对参数数量不确定的函数进行装饰:
def deco(func): def _deco(*args, **kwargs): print("before %s called."%func.__name__) ret = func(*args, **kwargs) print("after %s called. result: %s"%(func.__name__, ret)) return ret return _deco @deco # @deco的作用就相当于执行myfunc = deco(myfunc) def myfunc(a, b): print("myfunc(%s, %s) called."%(a, b)) return a + b @deco # @deco的作用就相当于执行myfunc = deco(myfunc2) def myfunc2(a, b, c): print("myfunc2(%s, %s, %s) called."%(a, b, c)) return a + b + c myfunc(1, 2) myfunc(3, 4) myfunc2(1, 2, 3) myfunc2(4, 5, 6)
property,让像使用属性一样调用函数。
property属性的两种实现方式:
①装饰器,即在方法上应用装饰器
类中属性有三种访问方式,分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法
class Goods():
def __init__(self):
self.money = 2
@property
def price(self):
print('@property')
return self.money
@price.setter
def price(self, value):
print('@price.setter')
self.money = value
@price.deleter
def price(self):
print('@price.deleter')
del self.money
g = Goods()
print(g.price) # 自动执行@property修饰的price方法,并获取方法的返回值
g.price = 3 # 自动执行@price.setter修饰的price方法,并将3赋值给该方法的参数
print(g.price)
del g.price # 自动执行price.deleter修饰的price方法
print(g.price)
②类属性,即在类中定义值为property对象的类属性
class Goods():
def __init__(self):
self.money = 2
def get_price(self):
print('getter')
return self.money
def set_price(self, value):
print('setter')
self.money = value
def del_price(self):
print('deleter')
del self.money
PRICE = property(get_price, set_price, del_price, 'description...')
g = Goods()
print(g.PRICE) # 自动调用第一个参数中定义的方法:get_price
g.PRICE = 3
print(g.PRICE) # 自动调用第二个参数中定义的方法:set_price
del g.PRICE # 自动调用第三个参数中定义的方法:del_price
print(g.PRICE)