0

I create several instances of my class in a loop and expect those to be independent. But to my confusion, when I create a new instance with the same name, it keeps properties of the instance created before.

So I have something like:

class myClass(object):
    def __init__(self, i1 = None, i2 = 'X', p1 = [], p2 = []):
        self.i1, self.i2 = i1,i2
        self.property1 = p1
        self.property2 = p2

    def doStuff(self):        
        self.property1.append(self.i1)
        self.property2.append(self.i2)
        print self.property1
        print self.property2

class mySubClass(myClass):
    def __init__(self, i1 = None, i2 = 'Z'):
        myClass.__init__(self, i1, i2)



inputTuples = (('A', 'B'), ('D', 'E'))

for x,y in inputTuples:
    o=mySubClass(x)
    pprint(vars(o))
    o.doStuff()
    print(id(o))


{'i1': 'A', 'i2': 'Z', 'property1': [], 'property2': []}
['A']
['Z']
37087832
{'i1': 'D', 'i2': 'Z', 'property1': ['A'], 'property2': ['Z']}
['A', 'D']
['Z', 'Z']
37088392

So for the 1st time it loops, pprint shows o.property1 =[] For the second time, it shows o.property1 is a list of whatever got appended to o in the first run of the loop.

My understanding was that when I call o=myClass(), a new instance of that class would be created and the old one will be deleted (effectively overwrtitten)

Could anyone explain to me how python works here and how I could make it work the way I want?

If I change the class to

class myClass(object):
    def __init__(self, i1 = None, i2 = 'X':
        self.i1, self.i2 = i1,i2
        self.property1 = []
        self.property2 = []

it works fine

{'i1': 'A', 'i2': 'Z', 'property1': [], 'property2': []}
['A']
['Z']
37087832
{'i1': 'D', 'i2': 'Z', 'property1': [], 'property2': []}
['D']
['Z']
37088392

I dont understand the fundamental difference here. Also, how can I keep the possibility of having p1 and p2 as input variables and still ahve the desired behaviour?

4

1 回答 1

3

我已将您的代码修改为实际可运行,并在o每次循环中显示对象的身份。最好去掉所有明显无关的东西,但也许这会让你更容易理解。

from pprint import pprint

def f(x, y):
    return x+y

class myClass(object):
    def __init__(self, i1,i2,i3):
        self.i1, self.i2, self.i3 = i1,i2,i3
        self.property1 =[]

    def doStuff(self):
        someValue = f(self.i1,self.i2)
        self.property1.append(someValue)

inputTuples = ((1, 2, 3), (4, 5, 6))

for x,y,z in inputTuples:
    o=myClass(i1=x,i2=y,i3=z)
    pprint(vars(o))
    o.doStuff()
    print(id(o))

当你运行它时,你会看到类似这样的输出:

{'i1': 1, 'i2': 2, 'i3': 3, 'property1': []}
4302258000
{'i1': 4, 'i2': 5, 'i3': 6, 'property1': []}
4302258064

换句话说,每个连续o的实例都有不同的属性,也是一个不同的对象。Python 确实o每次都在循环中创建一个新的。

它可能会或可能不会立即销毁旧实例,* 但您不在乎;它会“最终”摧毁它并做得足够好,所以你可以忘记它。


* 使用此特定代码,CPython 将立即销毁旧实例;PyPy、Jython 和 IronPython 通常会在下一个收集器通道中销毁它,但其中一些可能只是移动或标记它并在下一个通道中销毁它。

于 2013-07-03T19:43:50.143 回答