我创建了一个单词对象,它只包含两个方法,只需要两个参数。尽管有这种明显的简单性,但它的行为方式超出了我的理解范围:如果我创建同一个对象的两个实例,使用相同的第一个参数(在这种情况下为“disreading”),则第二个实例会以某种方式干扰第一个实例。打印实例表明它们确实是分开的,那么为什么以这种方式进行交互呢?
# Example tested with Python 2.7.3
from collections import namedtuple
DefinitionTuple = namedtuple("Definition", "word word_id text pos")
class Word(object):
def __init__(self, word, defs=None):
""""""
self.definitions = []
self.word = word
if defs != None:
for each in defs:
try:
each.pos
if each.word.lower() == self.word.lower():
self.definitions.append(each)
except AttributeError:
raise AttributeError("Definitions must be named tuples")
self.orderDefinitions()
def orderDefinitions(self):
""""""
ordered = sorted(self.definitions, key=lambda definition: definition.pos)
for i,each in enumerate(ordered):
each.pos = (i+1)
self.definitions = ordered
class Definition(object):
""""""
def __init__(self, definition):
"""Incoming arg is a single namedtuple"""
self.word = definition.word
self.word_id = definition.word_id
self.text = definition.text
self.pos = definition.pos
if __name__ == "__main__":
nt1 = DefinitionTuple("dissemble", 5, "text_string_a", 1)
nt2 = DefinitionTuple("dissemble", 5, "text_string_b)", 2)
nt3 = DefinitionTuple("dissemble", 5, "text_string_c", 3)
# Definiton objects
def_1 = Definition(nt1)
def_2 = Definition(nt2)
def_3 = Definition(nt3)
dissemble = Word("dissemble", [def_1, def_2, def_3])
print "first printing: "
for each in dissemble.definitions:
print each.pos, each.text
# create a new instance of Word ...
a_separate_instance = Word("dissemble", [def_3])
# ... and now the 'pos' ordering of my first instance is messed up!
print "\nnow note how numbers differ compared with first printing:"
for each in dissemble.definitions:
print each.pos, each.text
答案 0 :(得分:3)
您创建了Word
的新实例,但重用了def_3
的相同实例:
a_separate_instance = Word("dissemble", [def_3])
是有状态的。如果我们使用vars
:
print vars(def_3)
# create a new instance of Word ...
a_separate_instance = Word("dissemble", [def_3])
print vars(def_3)
我们看到了
{'text': 'text_string_c', 'word': 'dissemble', 'pos': 3, 'word_id': 5}
{'text': 'text_string_c', 'word': 'dissemble', 'pos': 1, 'word_id': 5}
归因于orderDefinitions
。
答案 1 :(得分:2)
在orderDefinitions
方法中,您要修改pos
个对象的Definition
属性:
each.pos = (i+1)
因此,当您第二次致电orderDefinitions
时,您将会def_3.pos = 1
。
但是,dissemble
包含对此def_3
对象的引用,其pos
属性现在已更改,因此您的问题。