クラスプロパティってできんのかな~と思って調べていた。
なるほどな~と思いつつ、この記事を読み返していた。
プロパティって(というかディスクリプタって)、インスタンスの生成元クラスのアトリビュートとして登録しておいて使うわけだから、クラスプロパティはクラスの生成元クラスにプロパティとして登録すればいいのでは?そんで、クラスの生成元クラスというのはつまりメタクラスでは?
というわけで、type
メタクラスのサブクラスにプロパティを登録して、それをメタクラスとしたクラスを作れば、その子は登録したプロパティが使えるはずや!
読み込み専用のクラスプロパティを作ってみまふ。
class PropertyXMeta(type): @property def x(self): return 0 @x.setter def x(self, value): raise AttributeError class Klass(metaclass=PropertyXMeta): pass if __name__ == '__main__': print(Klass.x) try: Klass.x = 5 except AttributeError: print("uh-huh, nice error.")
結果。
0 uh-huh, nice error.
Klass.x
に代入しようとするとAttributeError
が出るようになります。ガチもんの定数になりますね!(そこまでして変更不能にしたいかどうかはともかく)
上で見たような、@ClassProperty
といったデコレータをクラス内部に書いて使えるようにしたもののほうが実用的だとは思います。