2009-12-09 11 views
6

Estoy ejecutando un bucle for dentro de una función que crea instancias de una clase para probarlas. en lugar de crear nuevas clases, parece estar reutilizando los mismos dos una y otra vez.por qué python está reutilizando una instancia de clase dentro de la función

¿Hay algo que me falta acerca de cómo se manejan las clases y las variables en los métodos de python?

cómo puedo generar un nuevo objeto para cada iteración del bucle

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,) 

aquí es la salida

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 

cuando uso los nombres de variables separadas consigo las identificaciones separadas para cada instancia como se esperaba :

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))) 

salidas:

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 
+1

Parece que tiene un objeto de simulación de prueba allí ... es posible que desee comprobar cómo la creación de instancias de su clase simulada entra en juego en el caso de prueba. –

+0

@Jarret, buen punto, publicar la salida de los objetos de prueba en breve –

Respuesta

11

Todo lo que se muestra es que la memoria de los objetos se está reutilizando, no que los nuevos objetos no se estén instanciando. En cada iteración se sobrescribe collection, por lo que el recuento de referencias del objeto anterior se reduce y el intérprete de Python puede desasignar su memoria y reutilizarla (para el siguiente objeto).

>>> 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 

En este caso, se están reutilizando 2 ubicaciones de memoria. Si se va a añadir a una lista (o guardarlo en otro lugar), que sería preservada:

>>> 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 
3

de documentación de Python:

id() Devolver la “identidad” de un objeto. Este es un número entero (o entero largo) que garantiza ser único y constante para este objeto durante su vida útil. Dos objetos con tiempos de vida que no se superponen pueden tener el mismo valor de id().

+0

muy agradable, gracias por desenterrar esto –

Cuestiones relacionadas