2012-01-25 22 views
4

ここでは簡単なコードを示しますが、なぜそれが機能しないのか分かりません。属性を置き換える名前付きタプルのPythonリスト

from collections import namedtuple 

MyStruct = namedtuple('MyStruct', 'ThreadInstance ThreadName Mnemonic IpAddr IpGW Status Mode') 

Node = MyStruct(None, '', '', '', '', -1, 0) 
NodeDb = [] 
for id in range(4): 
    NodeDb.append(Node) 

NodeDb[2]._replace(ThreadName='T2') 
NodeDb[2]._replace(Mnemonic='ABCD') 
NodeDb[2]._replace(IpAddr='192.0.1.2') 
NodeDb[2]._replace(IpGW='192.0.1.3') 
NodeDb[2]._replace(Status=0) 
NodeDb[2]._replace(Mode=2) 

print(NodeDb) 

は、ここで出力

'>>> 
[MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0), 
MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0), 
MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0), 
MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0)]' 
+2

あなたが期待していた何を出力:要約中のSO

? –

+0

-1:完全にひどいタイトルです。事を意味するものではありません。役に立たない。 –

答えて

7

_replaceあなたはそう思わないと思います。 docsから:

somenamedtuple._replace(kwargsから)

戻り新しい値で指定されたフィールドを置き換えたタプルという名前の新しいインスタンス:

>>> p = Point(x=11, y=22) 
>>> p._replace(x=33) 
Point(x=33, y=22) 

あなたが呼んでいます_replaceですが、新しいNodeを保存することはありません。インプレースオブジェクトを変更する代わりに新しいオブジェクトを返す理由は、namedtuplesは定義上不変です。つまり、オブジェクトを作成した後は変更できません。

forループは、同じNodeへの4つの参照のリストを作成することに注意してください。この場合、作成しているオブジェクトはすべて同じで、namedtupleは不変ですが、これは一般的なことですので、これは実際問題ではありません。

from collections import namedtuple 

MyStruct = namedtuple('MyStruct', 'ThreadInstance ThreadName Mnemonic IpAddr IpGW Status Mode') 

NodeDb = [] 
Node = MyStruct(None, '', '', '', '', -1, 0) 
for id in range(4): 
    NodeDb.append(Node) 

NodeDb[2] = NodeDb[2]._replace(ThreadName='T2', 
           Mnemonic='ABCD', 
           IpAddr='192.0.1.2', 
           IpGW='192.0.1.3', 
           Status=0, 
           Mode=2) 

print(NodeDb) 
+1

ありがとうございます。 _replaceが新しいオブジェクトであることを指摘したので意味があります。 – scriptOmate

+0

@scriptOmate、よろしくお願いします。実際にあなたの質問に答えた場合は、答えを解決済みとしてマークすることができます:) –

1

C用語でポインタのような働きを念頭に、そのリスト内の各項目を保管してくださいです。 Python変数は常に参照によって渡され使用されます。それは、それが書かれています方法ですが、これは本当です:

assert NodeDb[0] is NodeDb[1] is NodeDb[2] is NodeDb[3] # True 

私はあなたが、その場合には、あなたがあなたのforループ内Node = MyStruct(...)を移動する必要があります別のオブジェクトのリストを、持っていたいと思います。

+0

一般的には正しいですが、すべてのオブジェクトが同じで不変なので、ここでは重要ではありません。実際、同じ名前のタプルのインスタンスを4つ作成するのは無駄です。 –

関連する問題