Python 装饰器与继承

25 投票
2 回答
20353 浏览
提问于 2025-04-15 23:42

帮帮我吧。我似乎无法让装饰器在继承中正常工作。我把它简化到我工作区里最简单的例子,但还是搞不定。

class bar(object):
    def __init__(self):
        self.val = 4
    def setVal(self,x):
        self.val = x
    def decor(self, func):
        def increment(self, x):
            return func( self, x ) + self.val
        return increment

class foo(bar):
    def __init__(self):
        bar.__init__(self)
    @decor
    def add(self, x):
        return x

哎呀,名字“decor”没有定义。

那用@bar.decor怎么样?类型错误:未绑定的方法“decor”必须用bar实例作为第一个参数(结果却得到了函数实例)。

那用@self.decor呢?名字“self”没有定义。

那用@foo.decor呢?!名字“foo”没有定义。

啊啊啊啊啊……我到底哪里出错了?

2 个回答

3

我知道这个问题在11年前就有人问过了……

我也遇到过同样的问题,这里是我用一个继承的私有装饰器解决这个问题的方法:

class foo:
    def __bar(func):
        def wrapper(self):
            print('beginning')
            func(self)
            print('end')
        return wrapper

class baz(foo):
    def __init__(self):
        self.quux = 'middle'
    @foo._foo__bar
    def qux(self):
        print(self.quux)

a = baz()
a.qux()

输出结果是:

beginning
middle
end
29

decor定义成一个静态方法,然后用@bar.decor这种形式来使用它:

class bar(object):
    def __init__(self):
        self.val = 4
    def setVal(self,x):
        self.val = x
    @staticmethod
    def decor(func):
        def increment(self, x):
            return func(self, x) + self.val
        return increment

class foo(bar):
    def __init__(self):
        bar.__init__(self)
    @bar.decor
    def add(self, x):
        return x

撰写回答