2010-12-03 15 views
7

Todos:¿Cómo puedo obtener una lista de referencias de un objeto en Python?

a = 1 
b = a 
c = b 

Ahora Quiero obtener una lista de objetos 1 etiquetado, que es [a, b, c]. ¿Cómo podría hacer esto?

Por cierto, ¿cómo llamar a la variable "a" aquí oficialmente? Sé hasta ahora que es una "etiqueta de objeto" para el objeto, pero no tengo idea de cuál es el término.

Gracias!

¿Por qué necesito esto:

a = b = c = 1 
print a, b, c 
1 1 1 
a = 2 
print a, b, c 
2 1 1 

en otro lenguaje como C, a, b, c debe ser de 2 si volver a asignar a = 2, pero en Python, no hay tal cosa como referencia, entonces la única manera de cambiar todo el valor de abc es a = b = c = 2 por lo que yo sé, es por eso que se propuso obtener toda la referencia de un objeto.

+0

¿Por qué? ¿Por qué quieres esto? ¿Qué posibles propósitos puede servir? –

+0

problema actualizado – user478514

+2

Ahora solo repite/qué/quiere, no/por qué/lo quiere. – pillmuncher

Respuesta

2

Lo que estás preguntando no es muy práctico y no es posible. Aquí hay una manera loca de hacerlo:

>>> a = 1 
>>> b = a 
>>> c = b 
>>> locals() 
{'a': 1, 'c': 1, 'b': 1, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None} 
>>> [key for key, value in locals().items() if value == 1] 
['a', 'c', 'b'] 
>>> globals() 
{'a': 1, 'c': 1, 'b': 1, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None} 
>>> [key for key, value in globals().items() if value == 1] 
['a', 'c', 'b'] 
+0

gracias, ese es un enfoque, pero eso no tiene ningún medio para mí en la semántica, mi pregunta es que trato de expresar la "variable" a, b, c es una "ref" del valor 1, son la misma referencia de valor 1, pero si defino otro d = 1, no hay duda que id (d) es igual que id (a), pero aquí creo que tiene la media de d.value = a.value pero no significa d = a aunque DO etiqueta el mismo objeto en python que conozco. – user478514

+0

@ user478514: eso demuestra levemente que * no se puede hacer *. –

+0

Creo que * se puede * hacer; ver mi respuesta a continuación. –

2

No es posible encontrar todas las referencias a un objeto dado en Python. Ni siquiera es posible encontrar todos los objetos o todas las referencias en Python. (La función CPython gc.get_objects hace esto, pero no es portable a través de implementaciones de Python.)

Usted puede utilizar dir() o locals() para encontrar todas las variables que existen en algún ámbito en el programa. Pero si los objetos se han definido en otros lugares, podrías pasarlos por alto con este método.

+0

Creo que su respuesta es errónea desde el punto de vista fáctico, teniendo en cuenta que 'objgraph' hace exactamente eso: encuentra referencias a un objeto dado. –

+0

@ErikAllik Esto solo es posible en algunas implementaciones de Python, ya que depende de características no portátiles del GC. Por ejemplo, no funcionará en Jython. Lo mencionaré en la respuesta, sin embargo. – Heatsink

9

Como puede ver, es imposible encontrarlos a todos.

>>> sys.getrefcount(1) 
791 
>>> sys.getrefcount(2) 
267 
>>> sys.getrefcount(3) 
98 
1

Antes que nada en C, "=" es una asignación de valores y no crea una referencia. Más específicamente cuando escribes a = b = 1, lo que sucede es esto.

(1) b = 1 se evalúa, asigna 1 a B y luego vuelve 1, por lo que la expresión se convierte a = 1

(2) a = 1 se evalúa, asigna 1 a B y luego devuelve 1 que no se usa en ninguna parte

Entonces a = 1 cambia solo a como se esperaba.

En python las cosas son un poco más complicadas ya que cada variable es una referencia, pero trata los números de manera diferente porque son inmutables. En resumen, cuando escribe a = 1 yb = 1, entonces a es b devuelve True. Pero cambiar uno no cambiará al otro.

Sin embargo, esto no sucede con los objetos, con ellos una referencia funciona como se esperaba. Entonces, si desea hacer lo que describe, quizás deba definir un nuevo objeto que contenga el valor que desea y asignarlo a una variable.

7

Me gustaría aclarar algunas informaciones erróneas aquí. Esto realmente no tiene nada que ver con el hecho de que "los ints son inmutables". Cuando escribe a = 2 está asignando a y a solo a algo diferente - no tiene ningún efecto en b y c.

Si se va a modificar una propiedad de a sin embargo, entonces se haría efecto b y c. Esperemos que este ejemplo ilustra mejor lo que estoy hablando:

>>> a = b = c = [1] # assign everyone to the same object 
>>> a, b, c 
([1], [1], [1]) 
>>> a[0] = 2   # modify a member of a 
>>> a, b, c 
([2], [2], [2])  # everyone gets updated because they all refer to the same object 
>>> a = [3]   # assign a to a new object 
>>> a, b, c 
([3], [2], [2])  # b and c are not affected 
3

Creo que podría estar interesado en objgraph. Le permite recorrer el gráfico del objeto en la memoria, o volcar un PNG de su gráfico de objetos. Es útil para depurar fugas de memoria.

Ver esta página: http://mg.pov.lt/objgraph/

0

Mira pyjack. Su función replace_all_refs parece funcionar bastante bien para reemplazar todas las referencias a un objeto. Nota: No funciona bien con objetos de cadena.

Cuestiones relacionadas