オプションで他のクラスに追加できるようにしたいメソッドを持ついくつかのクラスがあります。私の最初の解決策はミックスインを使用することでしたが、これは少し見苦しくなります:
class Schedule(Enumerator, Humanizer, Inferer, ...):
...
そこで、クラス デコレータを使用して同じ効果を実現できるのではないかと考えました。
@enumerator
@humanizer
@inferer
class Schedule(object):
...
デコレータ関数のサンプルは次のとおりです。
import inspect
def inferer(original_class):
from myproj.lib.inferer import Inferer
methods = inspect.getmembers(Inferer, predicate=inspect.ismethod)
for method in methods:
setattr(original_class, method[0], types.MethodTypes(method[1], original_class))
return original_class
...装飾されたクラスにメソッドとクラスメソッドを適切に追加するようです。ただし、これらの追加されたメソッド (またはクラスメソッド) のいずれかを装飾されたクラスで呼び出すと、いくつかのエラーが発生します。
メソッドの場合:
>>> Schedule().humanize()
TypeError: unbound method humanize() must be called with Humanizer instance as first argument (got type instance instead)
...これらがクラスメソッドとして追加されていることを示しているように見えるのはどれですか?
クラスメソッドの場合:
>>> schedule = Schedule.infer(foo)
TypeError: infer() takes exactly 2 arguments (3 given)
infer の定義に注意してください。
class Inferer(object):
@classmethod
def infer(cls, dates):
...
infer
として呼び出されたときに取得する引数を示すために、いくつかの行を追加しましたSchedule.infer()
。
cls: <class 'myproj.lib.inferer.Inferer'>
dates: <class 'myproj.Schedule'>
だから、私の質問:
これらの追加されたメソッドとクラスメソッドが奇妙な動作をする原因となるデコレータ関数の何が問題になっているのでしょうか? または、これらの追加を適切に処理するためにデコレータ関数を変更する方法を教えてください。
任意の点について明確にすることができるかどうか教えてください。