重複の可能性:
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