Pythonネタを書いたら、狙っていた通りckuwataさんが補足をくれたので追エントリしときます*1。ありがとうございます!
要するにこれは「class の直下で変数宣言をしたい」「でも普通にそれをやるとクラス変数になってしまう」という問題なわけだな。こういう場合にどうするかというと、プロパティを使うのが多分スマートだろう。
なるほど、確かにフィールドを直接触るよりプロパティを使うのが自然ですね。ただ、なんでもかんでもプロパティにするのかと思いきや、
ちなみに俺の方針としては、
- 外部仕様として公開するのならプロパティ
- そうでなければ __init__ 内部に列挙
というのがバランスのとれたやり方かなと思ってる。
とのこと。確かに、プロパティの記法は長いのでプライベート値まで全部作ってると泣けますね。
ちなみに、シャドーイングもかなり心惹かれる手法ですが*2、デコレータマニアとしてはドキュメントに出ていた、
class C(object): def __init__(self): self._x = None @property def x(self): """I'm the 'x' property.""" return self._x @x.setter def x(self, value): self._x = value @x.deleter def x(self): del self._x
が好きです。バージョン依存あるかもしれないですが。
で、クラス変数として定義すると結局何がまずいのさ?
順番おかしいですが、最後にクラス変数として定義しちゃ駄目な例をあげときます*3。listやdictはミュータブルなので、以下のようなコードは危険です。
>>> class Hoge(object): ... foo = [] ... >>> hoge1 = Hoge() >>> hoge1.foo.append("I'm hoge1.") >>> hoge2 = Hoge() >>> hoge2.foo ["I'm hoge1."]
逆にイミュータブルな値であれば、動きとしての問題はおきないし、デフォルト値を使い回すことでメモリの節約も狙えます。