python - 成员函数装饰器和 self 参数

标签 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对象。

我怎样才能在那里访问它?

最佳答案

通过包装函数逻辑(而不是实例)并将其重定向到类实例,您将丢失对有界实例的引用 - 此时,类实​​例自己的 self 应用而不是包装的实例方法,因为它在中间装饰器 (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')
# {}

关于python - 成员函数装饰器和 self 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51722976/

相关文章:

python - 如何在不同的图上绘制数据集

python - 防止 print() 语句覆盖 input() 语句中的文本

python - 在 python 3.7 中使用 exec() 导入别名不起作用

Python根据值列表创建所有字典的组合

python - Keras:精度非常低,损失非常高,并且每个输入的预测都是相同的

python - python中使用双引号和引号的区别

python - 装饰器 : TypeError: "got multiple values for keyword argument <variable name>" on function call

c++ - 装饰器模式 : Detaching responsibilities

从堆栈跟踪中隐藏装饰器的 Python 2 和 3 兼容方法

python - 如何使用 Django oAuth 工具包从 Django Rest Framework 获取请求应用程序详细信息