クラスデコレーターは、クラスを引数として受け取り、修正されたクラスまたはまったく新しいクラスを返す関数です。それらを使用することで、メソッドを動的に追加したり、既存のメソッドの動作を変更したり、元のクラスの機能を拡張するサブクラスを返したりできます。
def add_repr(cls): def __repr__(self): return f'<{cls.__name__}: {self.__dict__}>' cls.__repr__ = __repr__ return cls @add_repr class Point: def __init__(self, x, y): self.x = x self.y = y p = Point(3, 4) print(p) # <Point: {'x': 3, 'y': 4}>
add_repr は、適用されたすべてのクラスに動的に __repr__ メソッドを追加します。*args および **kwargs をサポートしていない場合、エラーが発生する可能性があります。連続して 2 つのクラスデコレーターを適用した場合、何が起こりますか?それらの適用順序は常に明確ですか?
デコレーターは「下から上」適用されます:まず、クラス宣言の直上にあるデコレーターが適用され、次にその上にあるものが適用されます。順序は非常に重要であり、最初のデコレーターの結果が次のデコレーターに渡され、以下のように続きます。
@dec1 @dec2 class Test: ... # 同等のもの: # Test = dec1(dec2(Test))
ストーリー
e-commerce アプリケーションでクラスのメソッドをログ記録しようとしましたが、デコレーターから誤って異なるオブジェクトを返し、メソッドがクラスの特性を失い、正しい継承ができなくなり、モデルの動作が壊れました。
ストーリー
新しいメソッドを自動生成するプロジェクトで、デコレーターアダプターを使用しましたが、サブクラスを返す際に super() を忘れました。その結果、階層と MRO が壊れ、子クラスで基本クラスの呼び出しが機能しなくなりました。
ストーリー
データパイプラインで、複数のデコレーター(ロガー、変更トラッカー)でクラスをラップしようとしましたが、適用順序が誤っていたため、メソッド名の衝突が発生し、「失われた」メソッドが原因で本番環境でバグが発生しました。