干扰物体(或者更不邪恶的东西?)

时间:2012-09-06 21:37:28

标签: python oop object

我创建了一个单词对象,它只包含两个方法,只需要两个参数。尽管有这种明显的简单性,但它的行为方式超出了我的理解范围:如果我创建同一个对象的两个实例,使用相同的第一个参数(在这种情况下为“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

2 个答案:

答案 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属性现在已更改,因此您的问题。