functools的update_wrapper方法理解

functools.update_wrapper(wrapper, wrapped): 它可以把被封装函数的namemoduledoc和 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>}
()
{}
>>> 


 

 

 

展开阅读全文