16

重複の可能性:
Python での最小の驚き: 変更可能なデフォルト引数

__init__Pythonコンストラクターの動作と意味を理解したいです。オプションのパラメーターがあり、既存のオブジェクトを新しいオブジェクトに設定しようとすると、既存のオブジェクトのオプションの値が保持されてコピーされるようです。

例を見てください:

以下のコードでは、ノードとおそらく多くの子を持つツリー構造を作成しようとしています。最初の classNodeBadでは、コンストラクターに値と可能な子の 2 つのパラメーターがあります。2 番目のクラスNodeGoodは、ノードの値のみをパラメーターとして受け取ります。どちらにもaddchild、子をノードに追加するメソッドがあります。

NodeGoodクラスでツリーを作成すると、期待どおりに機能します。しかし、同じことをNodeBadクラスで行うと、子を追加できるのは 1 回だけのようです。

以下のコードは、次の出力になります。

Good Tree
1
2
3
[< 3 >]
Bad Tree
1
2
2
[< 2 >, < 3 >]

ケパサ?

例は次のとおりです。

#!/usr/bin/python
class NodeBad:
  def __init__(self, value, c=[]):
    self.value = value
    self.children = c
  def addchild(self, node):
    self.children.append(node)
  def __str__(self):
    return '< %s >' % self.value
  def __repr__(self):
    return '< %s >' % self.value


class NodeGood:
  def __init__(self, value):
    self.value = value
    self.children = []
  def addchild(self, node):
    self.children.append(node)
  def __str__(self):
    return '< %s >' % self.value
  def __repr__(self):
    return '< %s >' % self.value

if __name__ == '__main__':
  print 'Good Tree'
  ng = NodeGood(1) # Root Node
  rootgood = ng
  ng.addchild(NodeGood(2)) # 1nd Child
  ng = ng.children[0]
  ng.addchild(NodeGood(3)) # 2nd Child

  print rootgood.value
  print rootgood.children[0].value
  print rootgood.children[0].children[0].value
  print rootgood.children[0].children

  print 'Bad Tree'
  nb = NodeBad(1) # Root Node
  rootbad = nb
  nb.addchild(NodeBad(2)) # 1st Child
  nb = nb.children[0]
  nb.addchild(NodeBad(3)) # 2nd Child

  print rootbad.value
  print rootbad.children[0].value
  print rootbad.children[0].children[0].value
  print rootbad.children[0].children
4

2 に答える 2

17

問題は、オプションの引数のデフォルト値が 1 つのインスタンスしかないことです。したがって、たとえば、 と言うと、オプションの引数がコードの呼び出しによって使用されるたびに、def __init__(self, value, c=[]):同じリストがメソッドに渡されます。[]

したがって、基本的にNoneは、オプションの引数のデフォルト値など、不変の日付型のみを使用する必要があります。例えば:

def __init__(self, value, c=None):

次に、メソッド本体で新しいリストを作成できます。

if c == None:
  c = []
于 2010-05-24T19:28:20.977 に答える
3

変更可能なデフォルト引数は混乱の元です。

この回答を参照してください:「最小の驚き」と可変デフォルト引数

于 2010-05-24T19:26:59.873 に答える