2つのスニペットは異なることを行うので、それは好みの問題ではなく、コンテキストでの正しい動作の問題です。Pythonのドキュメントで違いが説明されていますが、いくつかの例を次に示します。
展示物A
class Foo:
def __init__(self):
self.num = 1
これはバインドします num
Fooインスタンスにれます。このフィールドへの変更は、他のインスタンスには反映されません。
したがって:
>>> foo1 = Foo()
>>> foo2 = Foo()
>>> foo1.num = 2
>>> foo2.num
1
展示物B
class Bar:
num = 1
これはnum
Barクラスにバインドしますます。変更が伝播されます!
>>> bar1 = Bar()
>>> bar2 = Bar()
>>> bar1.num = 2
>>> bar2.num
1
>>> Bar.num = 3
>>> bar2.num
3
>>> bar1.num
2
>>> bar1.__class__.num
3
実際の答え
クラス変数は必要ないが、インスタンス変数のデフォルト値を設定するだけでよい場合、両方のメソッドは同等に優れていますか?またはそれらの1つは他よりも「pythonic」ですか?
展示Bのコードは、これについては明らかに間違っています。クラス属性(インスタンス作成時のデフォルト値)を単一のインスタンスにバインドするのはなぜですか?
展示Aのコードは大丈夫です。
ただし、コンストラクターでインスタンス変数のデフォルトを指定する場合は、次のようにします。
class Foo:
def __init__(self, num = None):
self.num = num if num is not None else 1
...あるいは:
class Foo:
DEFAULT_NUM = 1
def __init__(self, num = None):
self.num = num if num is not None else DEFAULT_NUM
...または:(望ましいですが、不変の型を扱っている場合に限ります!)
class Foo:
def __init__(self, num = 1):
self.num = num
このようにして、次のことができます。
foo1 = Foo(4)
foo2 = Foo()
self.attr = attr or []
内に書き込むだけ__init__
です。それは同じ結果を達成し(私は思う)、それでも明確で読みやすいです。