import time class A(object): def __init__(self, t): print('实例化一个A类对象……') self.t = t def __call__(self, f): def inner_A(*args, **kwargs): print('延迟{}秒后开始执行……'.format(self.t)) time.sleep(self.t) print('{}函数开始运行……'.format(f.__name__)) f(*args, **kwargs) print('{}函数结束运行……'.format(f.__name__)) return inner_A @A(1) def do_something(name): print('你好,{}!'.format(name)) if __name__ == '__main__': do_something('姚明')
输出结果:
实例化一个A类对象……
延迟1秒后开始执行……
do_something函数开始运行……
你好,姚明!
do_something函数结束运行……
无论是函数装饰器还是类装饰器,原理上是一样的,区别在于如果A是函数,A()是直接调用函数,而A是类时,A()是实例化,通过A()()是调用A类的__call__方法。
4 Python中内置的装饰器 4.1 @property,@setter,@deleter@property,@setter,@deleter这���个装饰器提供了更加友好的方式来获取、设置或删除类中的属性。@property装饰器所装饰的函数可以像访问属性一样调用函数,注意,@property装饰器必须先于@setter,@deleter使用,且三者说装饰的函数必须同名。
class A(object): def __init__(self, v): print('实例化一个A类对象……') self.__value = v @property def value(self): print('取值时被调用') return self.__value @value.setter def value(self, value): print('赋值时被调用') self.__value = value @value.deleter def value(self): print('删除值时被调用……') del self.__value if __name__ == '__main__': a = A(123) print('-------------') print('__value的值为:{}'.format(a.value)) print('-------------') a.value = 234 print('__value的值为:{}'.format(a.value)) print('--------------') del a.value print('__value的值为:{}'.format(a.value))
输出为:
Traceback (most recent call last):
实例化一个A类对象……
-------------
取值时被调用
File "E:/WorkProjectCode/study_pymysql/study_secorators/test2.py", line 33, in <module>
__value的值为:123
-------------
print('__value的值为:{}'.format(a.value))
赋值时被调用
取值时被调用
__value的值为:234
File "E:/WorkProjectCode/study_pymysql/study_secorators/test2.py", line 11, in value
--------------
return self.__value
删除值时被调用……
取值时被调用
AttributeError: 'A' object has no attribute '_A__value'
运行产生异常,因为最后访问了已经删除了的元素。
4.2 @classmethod在一个类中,如果一个方法被@classmethod所装饰,就代表该方法与类绑定,而不是与实例对象绑定,第一个参数cls由Python机制自动传递,表示类本身。