以下成员函数装饰器的最小示例:
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')
{}
所以self
是args
之一。
但是,当使用包装类时:
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',)
{}
因此引用self
对象的Foo
在__call__
对象的WrappedFunction
的正文中是不可访问的。
如何在此访问它?
答案 0 :(得分:2)
通过包装函数逻辑(而不是实例)并将其重定向到类实例,您将丢失对 bounded 实例的引用-此时,类实例自己的{{1 }}而不是包装实例方法,因为它在中间修饰器(self
)中丢失。
您要么必须包装对包装好的函数的调用,然后将wrap_function()
/ *args
传递给它,要么只是创建一个合适的包装类,而不是添加中间包装:
**kwargs
答案 1 :(得分:1)
很遗憾,但这可能是您在__call__
函数中需要的唯一解决方案。
建议您检查一下:What is the difference between __init__ and __call__ in Python?
def wrap_function(func):
def wrapper(*args, **kwargs):
x = WrappedFunction(func)
x(*args, **kwargs)
return wrapper