継承されたメソッドでデコレータを使用する方法がよくわかりません。通常、デコレータは定義の前に配置されますが、継承された関数の場合、定義は子クラスではなく親で指定されます。子クラスのメソッドの定義を書き直さずに、継承されたメソッドの周りにデコレータを配置するように指定したいと思います。
自分自身を明確にするために、これが私が意味することの実際的な例です:
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()
この例で行われている方法は機能しますが、メソッドを元のメソッドの呼び出しに置き換えてデコレータを配置できるようにするだけで、私にはどういうわけか奇妙に見えます。また、これを機能させるには、メソッドを親クラスのclassmethodとして定義する必要があります。
私は何かが足りないのですか?経験豊富な開発者はこれをどのように行いますか?
どんな助け、洞察、批判的なコメントと無料のコーヒーも大歓迎です!
デコレータ構文でデコレータを使用する必要はありません。それはただの呼び出し可能です:
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)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加