1. ホーム
  2. python

[解決済み] Pythonでインスタンス変数のデフォルト値をどのように宣言すればよいですか?

2022-12-26 12:39:23

質問

クラスのメンバにデフォルト値を与えるべきでしょうか?

class Foo:
    num = 1

とか、こんな感じ?

class Foo:
    def __init__(self):
        self.num = 1

この質問 の両方で発見しました。

bar = Foo()
bar.num += 1

はよく定義された操作です。

最初のメソッドがクラス変数を与えるのに対して、2番目のメソッドはそうでないことは理解しています。しかし、私がクラス変数を必要とせず、インスタンス変数にデフォルト値を設定する必要がある場合、両方の方法は同じように良いですか?それとも、どちらかが他よりも「パイソン的」なのでしょうか?

私が気づいたことの1つは、Djangoチュートリアルで を使うと、モデルを宣言するのに2番目の方法を使うということです。 個人的には 2 番目の方法の方がエレガントだと思うのですが、「標準的な」方法は何なのか知りたいところです。

どのように解決するのですか?

bpの回答を拡張して、私は彼がimmutable型によって何を意味するのかを示したいと思いました。

まず、これは大丈夫です。

>>> class TestB():
...     def __init__(self, attr=1):
...         self.attr = attr
...     
>>> a = TestB()
>>> b = TestB()
>>> a.attr = 2
>>> a.attr
2
>>> b.attr
1

しかし、これはimmutable(変更不可)な型に対してのみ動作します。もしデフォルト値がmutable(置き換えられるという意味)であれば、代わりにこれが起こるでしょう。

>>> class Test():
...     def __init__(self, attr=[]):
...         self.attr = attr
...     
>>> a = Test()
>>> b = Test()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[1]
>>> 

ただし ab には共有属性があります。これはしばしば望まれないことです。

これは、インスタンス変数がmutableである場合に、デフォルト値を定義するためのPythonicな方法です。

>>> class TestC():
...     def __init__(self, attr=None):
...         if attr is None:
...             attr = []
...         self.attr = attr
...     
>>> a = TestC()
>>> b = TestC()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[]

私の最初のコードが動作する理由は、不変の型では、Pythonは必要なときにいつでもその新しいインスタンスを作成するからです。もし1に1を足す必要があるなら、古い1は変更できないので、Pythonはあなたのために新しい2を作成します。その理由は、主にハッシュ化のためだと私は考えています。