如何在子类中装饰继承的方法?
我不太确定如何在继承的方法上使用装饰器。通常,装饰器是在定义之前加上的,但对于继承的函数,定义是在父类中,而不是子类中。我想避免在子类中重写这个方法的定义,而是简单地指定在继承的方法周围加上装饰器。
为了让我的意思更清楚,这里有一个我想表达的工作示例:
class Person():
def __init__(self, age):
self.age = age
@classmethod
def gets_drink(cls, ):
print "it's time to get a drink!"
return "A beer"
def dec(some_f):
def legal_issue(obj,):
some_f(obj)
return 'A Coke'
return legal_issue
class Child(Person):
def __init__(self, age):
Person.__init__(self, age=age)
#in principle i'd like to write
#@dec
#self.gets_drink
#which does not work
#the only working way I found is by defining the method as a classmethod
#and write this:
@dec
def gets_drink(self, ):
return Person.gets_drink()
dad = Person(42)
son = Child(12)
print dad.gets_drink()
print son.gets_drink()
这个示例中的做法是有效的,但我觉得有点奇怪,因为它用一个调用原始方法的方式来替换这个方法,只是为了能加上装饰器。而且,为了让这个方法能正常工作,它需要在父类中被定义为类方法。
我是不是漏掉了什么?有经验的开发者会怎么做呢?
任何帮助、见解、批评意见和免费的咖啡都非常感谢!
相关问题:
1 个回答
20
你不一定要用装饰器的语法来使用装饰器。它其实就是一个可以调用的东西:
class Child(Person):
def __init__(self, age):
Person.__init__(self, age=age)
gets_drink = dec(Person.gets_drink.__func__)
这个做法会把装饰器的返回值添加到子类中,作为一个同名的方法。__func__属性可以把绑定的(类)方法解包,拿到原始的函数。
需要注意的是,你的新方法现在是一个普通的方法,而不是类方法。如果你想让它成为类方法,就得把结果重新用classmethod()包裹起来。
这个做法之所以有效,是因为下面的语法:
@decorator_expression
def function_definition():
pass
其实只是一些语法上的简化,等同于:
def function_definition():
pass
function_definition = decorator_expression(function_definition)