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 装饰器和继承的主要内容,如果未能解决你的问题,请参考以下文章