以下关于成员函数的装饰器的最小示例:
def wrap_function(func):
def wrapper(*args,**kwargs):
print(args)
print(kwargs)
return wrapper
class Foo:
@wrap_function
def mem_fun(self,msg):
pass
foo = Foo()
foo.mem_fun('hi')
输出:
(<__main__.Foo object at 0x7fb294939898>,'hi')
{}
所以自我就是其中的一个.
但是在使用包装类时:
class WrappedFunction:
def __init__(self,func):
self._func = func
def __call__(self,*args,**kwargs):
print(args)
print(kwargs)
def wrap_function(func):
return WrappedFunction(func)
class Foo:
@wrap_function
def mem_fun(self,msg):
pass
foo = Foo()
foo.mem_fun('hi')
输出是:
('hi',)
{}
因此,引用Foo对象的self不能在WrappedFunction对象的__call__体中访问.
我怎样才能在那里访问它?
最佳答案
通过包装函数逻辑(但不是实例)并将其重定向到类实例,您将丢失对有界实例的引用 – 此时,类实例自己应用而不是包装的实例方法,因为它在中间装饰器(wrap_function()).
您要么必须将调用包装到包装函数并将* args / ** kwargs传递给它,要么只是创建一个正确的包装类而不是添加中间包装器:
class WrappedFunction(object):
def __call__(self,func):
def wrapper(*args,**kwargs):
print(args)
print(kwargs)
# NOTE: `WrappedFunction` instance is available in `self`
return wrapper
class Foo:
@WrappedFunction() # wrap directly,without an intermediary
def mem_fun(self,msg):
pass
foo = Foo()
foo.mem_fun('hi')
# (<__main__.Foo object at 0x000001A2216CDBA8>,'hi')
# {}