注意:
另一个问题的公认答案显示了如何使用父装饰器。
这个问题的公认答案显示将decorator移动到模块范围。
编辑:使用前面的例子是个坏主意。希望这更清楚:
class A:
def deco( func ):
print repr(func)
def wrapper( self, *args ):
val = func( *args )
self.do_something()
return val
return wrapper
def do_something( self ):
# Do something
print 'A: Doing something generic for decoration'
@deco
def do_some_A_thing ( self ):
# Do something
print 'A: Doing something generic'
class B ( A ):
@deco
def do_some_B_thing( self ):
# Do something
print "B: Doing something specific"
a = A()
b = B()
a.do_some_A_thing()
b.do_some_B_thing()
#Expected Output:
#A: Doing something generic
#A: Doing something generic for decoration
#B: Doing something specific
#A: Doing something generic for decoration
此代码生成名称错误:名称“deco”未在B中定义。 decorator需要在类范围内,因为我需要访问存储状态。
第三次编辑:在斯文的建议下,我尝试了:
class A:
def deco( func ):
def wrapper( self, *args ):
val = func( *args )
self.do_something(*args)
return val
return wrapper
def do_something( self ):
# Do something
print 'A: Doing something generic for decoration'
@deco
def do_some_A_thing ( self ):
# Do something
print 'A: Doing something generic'
deco = staticmethod(deco)
class B ( A ):
@A.deco
def do_some_B_thing( self ):
# Do something
print "B: Doing something specific"
a = A()
b = B()
a.do_some_A_thing()
b.do_some_B_thing()
#Expected Output:
#A: Doing something generic
#A: Doing something generic for decoration
#B: Doing something specific
#A: Doing something generic for decoration
我现在有了TypeError:do_some_A_thing()只接受1个参数(0给定)。有什么线索吗?
已编辑问题的答案:您的问题已成为question it linked to before the edit的完全副本。与链接问题的答案中给出的解决方案相比,一个更简单的解决方案是将decorator移出类命名空间。
而且,
self.do_something(self)
应该是self.do_something()
而不是——不要通过self
两次。在编辑之前回答问题:如果您只想用decorator修饰实例方法,请不要将
self
参数折叠成*args
,而应使其显式:也就是说,我看不出在类名称空间中包含
_deco
并将其转换为staticmethod
的意义。只需将其移动到模块名称空间。问题是继承只适用于实例属性查找,而不适用于类定义。所以当你试图用B中的A.deco装饰时,它找不到。解决方案是将
deco
移到模块作用域,并且由于名称self
没有任何魔力,因此可以继续使用它。您还需要显式地将self
传递给func
,并且您确实需要将它传入self.do_something()
。下面是更新的代码:相关问题 更多 >
编程相关推荐