これは、メタクラスで__getattr__
フックを使用して実現できます。
class DefaultClassMethods(type):
def __getattr__(cls, attr):
def _defaultClassMethod(cls):
print 'Hi, I am the default class method!'
setattr(cls, attr, classmethod(_defaultClassMethod))
return getattr(cls, attr)
デモ:
>>> class DefaultClassMethods(type):
... def __getattr__(cls, attr):
... def _defaultClassMethod(cls):
... print 'Hi, I am the default class method!'
... setattr(cls, attr, classmethod(_defaultClassMethod))
... return getattr(cls, attr)
...
>>> class A(object):
... __metaclass__ = DefaultClassMethods
...
>>> A.spam
<bound method DefaultClassMethods._defaultClassMethod of <class '__main__.A'>>
>>> A.spam()
Hi, I am the default class method!
classmethod
呼び出しの結果をクラスに直接設定し、将来のルックアップのために効果的にキャッシュしていることに注意してください。
代わりに、すべての呼び出しでクラス メソッドを再生成する必要がある場合は、同じメソッドを使用して関数をインスタンスにバインドしますが、代わりにクラスとメタクラスを使用cls.__metaclass__
します (メタクラスのサブクラス化と一貫性を保つために使用します)。
from types import MethodType
class DefaultClassMethods(type):
def __getattr__(cls, attr):
def _defaultClassMethod(cls):
print 'Hi, I am the default class method!'
return _defaultClassMethod.__get__(cls, cls.__metaclass__)
静的メソッドの場合、すべての場合に関数を直接返すだけで、staticmethod
デコレータや記述子プロトコルをいじる必要はありません。