4

class 属性が 以外に設定されている Python クラスがありますNone。新しいインスタンスを作成すると、その属性に加えられた変更はすべてのインスタンスで永続化されます。

これを理解するためのコードを次に示します。

 class Foo(object):
   a = []
   b = 2

 foo = Foo()
 foo.a.append('item')
 foo.b = 5

予想どおり、 returnとfoo.areturnsを使用します。['item']foo.b5

新しいインスタンスを作成するとき (これを と呼びます)、 returnとreturnもbar使用しbar.aます! ただし、最初にすべてのクラス属性をに設定すると、次のように に設定されます。['item']bar.b5None__init__

 class Foo(object):
   a = None
   b = None

   def __init__(self):
     self.a = []
     self.b = 2

bar.aリターン[]bar.bリターンを使用し2ながら、foo.aリターン['item']とリターンをfoo.b返します5

これはどのように機能すると思われますか?Python をプログラミングしてきた 3 年間、この問題に遭遇したことはないようです。ドキュメントのどこにも見つからないので、可能であれば参考にしていただければ幸いです。:)

4

4 に答える 4

8

はい、これが機能するはずの方法です。

aとが のインスタンスb属している場合、これを行う正しい方法は次のとおりです。Foo

class Foo(object):
   def __init__(self):
     self.a = []
     self.b = 2

以下は、クラス自体aを作成し、クラスにb属しているため、すべてのインスタンスが同じ変数を共有します。

class Foo(object):
   a = []
   b = 2

2 番目の例で行ったように、2 つの方法を混在させると、何も役に立たず、混乱を招くだけです。

言及する価値のある警告の 1 つは、最初の例で次のことを行う場合です。

foo.b = 5

変更していません。その「影」Foo.bに新しい属性を追加しています。これを行うと、どちらも変更されません。その後 を実行すると、その属性が削除され、再び が参照されます。fooFoo.bbar.bFoo.bdel foo.bfoo.bFoo.b

于 2011-10-26T14:10:41.357 に答える
1

はい、最初は驚くべきことのように思えますが、他の回答で述べたように、これが python の動作です。これで切り捨てられずに 3 年間 python を使用しましたか? あなたはラッキーです、とてもラッキーです。私があなただったら、小動物の機密の過去のコードをチェックします...

関数呼び出しにも注意してくださいdef func(list=[])。驚くべきことに、同様の動作があります。

そして、可能であれば、コミット フックに pylint 解析をプラグインします。または、少なくともコードで pylint を実行すると、非常に有益であり、おそらくこのトリックについて説明したことでしょう (これはトリックではなく、実際には非常に論理的で直交的であり、python の方法です)。

于 2011-10-26T16:31:23.603 に答える
1

はい、それはまさにあなたが期待すべきことです。クラスで変数を定義すると、それらの属性はインスタンスではなくクラスに関連付けられます。インスタンスの属性に割り当てると、インスタンスがクラス属性をマスクして新しい値を取得することに常に気付くとは限りません。その場で変更するメソッドはlist.append、たまたまクラスの属性である既存のオブジェクトを変更するだけなので、インスタンスに新しい属性を与えません。

クラスのすべてのインスタンスが属性に対して独自の一意の値を持つ必要があるときはいつでも、通常は__init__メソッドでそれを設定して、インスタンスごとに異なることを確認する必要があります。

クラスに適切なデフォルト値を持つ属性があり、その値がintまたはなどの不変型 (その場で変更できない) である場合にのみstr、クラスに属性を設定する必要があります。

于 2011-10-26T14:14:53.650 に答える
0

クラス属性とインスタンス属性を混同しています。最初の例では、クラス属性aとのみがありbますが、2 番目の例では、同じ名前のインスタンス属性もあります。

インスタンス属性がない場合、Python はインスタンスからクラスへの属性への参照を通過するようです (今日、新しいことを学びました)。

このコードは参考になるかもしれません:

class Foo:
  a = 1
  b = 2

  def __init__(self):
    self.a=3

print Foo.a   # => 1
print Foo().a # => 3
print Foo.b   # => 2
print Foo().b # => 2
于 2011-10-26T14:14:22.550 に答える