我在循环中创建了我的类的几个实例,并期望它们是独立的。但令我困惑的是,当我创建一个具有相同名称的新实例时,它会保留之前创建的实例的属性。
所以我有类似的东西:
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
所以第一次循环,pprint显示o.property1 = [] 第二次,它显示o.property1是在循环的第一次运行中附加到o的任何内容的列表。
我的理解是,当我调用o = myClass()时,将创建该类的新实例,并删除旧实例(有效地覆盖)
有人可以向我解释一下python在这里是如何工作的,以及我如何让它按照我想要的方式工作?
如果我将课程改为
class myClass(object):
def __init__(self, i1 = None, i2 = 'X':
self.i1, self.i2 = i1,i2
self.property1 = []
self.property2 = []
一切正常
{'i1': 'A', 'i2': 'Z', 'property1': [], 'property2': []}
['A']
['Z']
37087832
{'i1': 'D', 'i2': 'Z', 'property1': [], 'property2': []}
['D']
['Z']
37088392
我不明白这里的根本区别。另外,如何保持将p1和p2作为输入变量的可能性仍然是理想的行为?
答案 0 :(得分: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通常会在下一次收集器传递中销毁它,但是其中一些可能只是移动或标记它并在下一次传递中将其销毁。