Python 装饰器和继承

Posted

技术标签:

【中文标题】Python 装饰器和继承【英文标题】:Python Decorators and inheritance 【发布时间】:2011-03-01 09:03:32 【问题描述】:

帮助一个人。似乎无法让装饰器与继承一起工作。将其分解为我的暂存工作区中最简单的小示例。似乎仍然无法正常工作。

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 怎么样? TypeError: unbound method "decor" must be called with a bar instance as first argument (得到函数实例)

好的,@self.decor 怎么样?名称“self”未定义。

好的,@foo.decor 怎么样?!名称“foo”未定义。

AaaaAAAaAaaaarrrrgggg...我做错了什么?

【问题讨论】:

在您的示例中,您可以在foo 中使用return x + self.val 来定义add。你不能在你的实际代码中这样做吗? 这是一个精炼的示例代码,突出了我所面临的问题。如果代码那么简单,那么是的。然而,事实并非如此。 【参考方案1】:

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

【讨论】:

这会更好,因为self 没有在两个函数定义中使用。 @EShull:实际上,decor 可以是静态方法,尽管有 self 引用。 self 仅在increment() 内部被引用,当在foo 实例上调用f.add(10) 时,increment() 内部的self 参数将引用f,并且增量将按预期工作。 这看起来可行。必须下班,但如果真的下班,我会将此标记为答案。谢谢! 这目前有效吗?它不会引发TypeError: staticmethod is not callable吗?【参考方案2】:

我知道这个问题已经在 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

【讨论】:

以上是关于Python 装饰器和继承的主要内容,如果未能解决你的问题,请参考以下文章

Python 装饰器和装饰器模式有啥区别?

python中的无参装饰器和有参装饰器

装饰器与继承

python函数下篇装饰器和闭包,外加作用域

python 装饰器和 functools 模块

python -- 迭代器和装饰器