成员函数装饰器和自变量

时间:2018-08-07 09:08:56

标签: python python-3.x decorator wrapper member-functions

以下成员函数装饰器的最小示例:

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')
{}

所以selfargs之一。

但是,当使用包装类时:

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的正文中是不可访问的。

如何在此访问它?

2 个答案:

答案 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