__getattribute__
はSchwobasegglの回答のようにカスタマイズできますが、カスタムメタクラスを使用することもできます。
Pythonで「メタクラス」と言えば、通常は__new__
メソッドをオーバーライドし、クラス作成時に(インスタンス作成時とは対照的に)複雑な作業を行うと考えられます。ただし、すべての特別なダンダー(__these__ __methods__
)を残しておくと、メタクラスはクラスのクラスに過ぎず、すべてのメソッドはクラス自体からは見えますが、クラスのインスタンスからは表示されません。つまり、1つのインスタンスがインスタンスであるときには表示されませんが、インスタンスでクラスを直接参照することはできません。 (もちろん、人は常にself.__class__.method
を行うことができます、が)
また、複雑さのmetaclasseの正当悪い-名声にもかかわらず、__getattribute__
自体をオーバーライドすることは、いくつかのpitfallsを持つことができます。この特定の場合、あなたはalreaydメタクラス使用守りたいclasssで
- 「普通の」メタクラスが使用するとは異なりますが、この特定の使用を、普通のクラス階層のように自由に構成可能になります
class ClsMethods(BaseModel):
# inherit from `type` if there is no metaclass already
# now, just leave __new__, __init__, __prepare__ , alone
# and write your class methods as ordinary methods:
def update(cls, *args, **kw):
...
def fetch_rows_from(self, ...):
...
class Model(with_metaclass(ClsMethods)):
# This really socks. Do you really still need Py2 support? :-)
...
(それは明白であるが、あなたはクラスメソッドとしてメタクラスで メソッドを宣言する必要はありません知覚する必要があります。それらのすべてが クラスでメタクラスのインスタンスのためのクラスメソッド、です)
とAT迅速なデモコンソール:
In [37]: class M(type):
...: def secret(cls): print("At class only")
...:
In [38]: class A(metaclass=M):
...: pass
...:
In [39]: A.secret()
At class only
In [40]: A().secret()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-40-06355f714f97> in <module>()
----> 1 A().secret()
AttributeError: 'A' object has no attribute 'secret'
私はあなたが 'classmethod'でそれを行うことはできないと思います。インスタンスにバインドされているかどうかをチェックし、例外が発生するかどうかを調べる 'classmethod'に似た独自の記述子を書く必要があります。 – BrenBarn