python – 成员函数装饰器和自我参数

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

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

相关文章

我最近重新拾起了计算机视觉,借助Python的opencv还有face_r...
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Poolin...
记得大一学Python的时候,有一个题目是判断一个数是否是复数...
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic ...
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic v...
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic ...