functools.update_wrapper(wrapper, wrapped): 它可以把被封装函数的name、module、doc和 dict都复制到封装函数去。
>>> def a(func):
def rt(*args, **kwargs):
print('rt...')
print(rt)
import functools
functools.update_wrapper(rt, func)
print(rt)
return rt
>>> @a
def b():
print('b...')
<function a.<locals>.rt at 0x0000000002FE16A8>
<function b at 0x0000000002FE16A8>
>>> b()
rt...
类装饰器,会把属性复制到类的__dict__中去:
>>> class A:
def __init__(self, func):
print('1: ', self)
import functools
functools.update_wrapper(self, func)
print('2: ', self)
def __get__(self, *args, **kwargs):
print('get...', args, kwargs, sep='\n')
def __call__(self, *args, **kwargs):
print('call...', self, args, kwargs, sep='\n')
>>> @A
def b():
print('b...')
1: <__main__.A object at 0x0000000002FBBDA0>
2: <__main__.A object at 0x0000000002FBBDA0>
>>> b
<__main__.A object at 0x0000000002FBBDA0>
>>> b()
call...
<__main__.A object at 0x0000000002FBBDA0>
()
{}
>>> class A:
def __init__(self, func):
print('1: ', self.__dict__)
import functools
functools.update_wrapper(self, func)
print('2: ', self.__dict__)
def __get__(self, *args, **kwargs):
print('get...', self.__dict__, args, kwargs, sep='\n')
def __call__(self, *args, **kwargs):
print('call...', self.__dict__, args, kwargs, sep='\n')
>>> @A
def b():
print('b...')
1: {}
2: {'__module__': '__main__', '__name__': 'b', '__qualname__': 'b', '__doc__': None, '__annotations__': {}, '__wrapped__': <function b at 0x0000000002FE1730>}
>>> b
<__main__.A object at 0x0000000003004C88>
>>> b()
call...
{'__module__': '__main__', '__name__': 'b', '__qualname__': 'b', '__doc__': None, '__annotations__': {}, '__wrapped__': <function b at 0x0000000002FE1730>}
()
{}
>>>