为什么Python在函数内部复用类实例
我在一个函数里运行了一个循环,这个循环用来创建一个类的实例进行测试。但是我发现,它似乎一直在重复使用同两个实例,而不是每次都创建新的。
我是不是对Python中的类和变量处理有什么误解呢?
我该如何在循环的每次迭代中生成一个新的对象呢?
class CollectionSetImages(unittest.TestCase):
def test_keywordset(self):
"""Testing keyword queries by images equality """
for keyword in ['a','b','c','d','e','f','g']:
images_by_keyword = Image.keyword_query([keyword])
collection = Collection([keyword])
class_images = collection.images
print('colleciton: %s id: %s' % (collection,id(collection)))
self.assertEqual(images_by_keyword, class_images,)
这是输出结果
colleciton: <tests.fakeimages._FakeCollection object at 0xb7c656cc> id: 3083228876
colleciton: <tests.fakeimages._FakeCollection object at 0xb7c656ec> id: 3083228908
colleciton: <tests.fakeimages._FakeCollection object at 0xb7c656cc> id: 3083228876
colleciton: <tests.fakeimages._FakeCollection object at 0xb7c656ec> id: 3083228908
colleciton: <tests.fakeimages._FakeCollection object at 0xb7c656cc> id: 3083228876
colleciton: <tests.fakeimages._FakeCollection object at 0xb7c656ec> id: 3083228908
colleciton: <tests.fakeimages._FakeCollection object at 0xb7c656cc> id: 3083228876
当我使用不同的变量名时,每个实例的ID都是不同的,正如我预期的那样:
collectionA = Collection(['a'])
print('collection: %s id: %s' % (collectionA,id(collectionA)))
collectionB = Collection(['f'])
print('collection: %s id: %s' % (collectionB,id(collectionB)))
collectionC = Collection(['f'])
print('collection: %s id: %s' % (collectionC,id(collectionC)))
输出结果:
collection: <tests.fakeimages._FakeCollection object at 0xb7cbc8ac> id: 3083585708
collection: <tests.fakeimages._FakeCollection object at 0xb7cbccec> id: 3083586796
collection: <tests.fakeimages._FakeCollection object at 0xb7cbcd2c> id: 3083586860
2 个回答
4
来自Python文档:
id() 是一个函数,用来返回一个对象的“身份”。这个身份是一个整数(或者长整数),在这个对象的整个生命周期内都是唯一的和不变的。也就是说,只要这个对象还在,它的身份就不会改变。不过,如果两个对象的生命周期没有重叠,它们可能会有相同的 id() 值。
11
这段话的意思是,显示的只是对象的内存被重复使用,并不能说明没有创建新的对象。在每次循环中,collection
的内容被覆盖了,因此之前对象的引用计数减少,Python解释器就可以释放它的内存并重新使用(给下一个对象)。
>>> for a in range(1,5):
... b = object()
... print b, id(b)
...
<object object at 0xb7db9470> 3084620912
<object object at 0xb7db9468> 3084620904
<object object at 0xb7db9470> 3084620912
<object object at 0xb7db9468> 3084620904
<object object at 0xb7db9470> 3084620912
在这种情况下,有两个内存位置被重复使用。如果你把它添加到一个列表中(或者保存到其他地方),那么它就会被保留下来:
>>> a = []
>>> for b in range(1,5):
... c = object()
... a.append(c)
... print c, id(c)
...
<object object at 0xb7db9470> 3084620912
<object object at 0xb7db9468> 3084620904
<object object at 0xb7db9478> 3084620920
<object object at 0xb7db9480> 3084620928