2012-05-28 20 views
18

En Python, ¿es posible obtener el objeto, digamos Foo, que contiene otro objeto, Bar, desde dentro de Bar? Aquí hay un ejemplo de lo que quiero decirObteniendo objeto contenedor/padre dentro de python

class Foo(object): 
    def __init__(self): 
     self.bar = Bar() 
     self.text = "Hello World" 

class Bar(object): 
    def __init__(self): 
     self.newText = foo.text #This is what I want to do, 
           #access the properties of the container object 

foo = Foo() 

¿Esto es posible? ¡Gracias!

+2

Tienes un error tipográfico; en 'Foo .__ init__',' self.bar = Foo() 'debe ser' self.bar = Bar() '. De lo contrario, tienes un bucle infinito (para crear un Foo, primero debes crear un Foo). –

+0

¡Gracias, arreglado! :) –

Respuesta

29

pasa una referencia al objeto de bar, de este modo:

class Foo(object): 
    def __init__(self): 
     self.text = "Hello World" # has to be created first, so Bar.__init__ can reference it 
     self.bar = Bar(self) 

class Bar(object): 
    def __init__(self, parent): 
     self.parent = parent 
     self.newText = parent.text 

foo = Foo() 

Editar: como ha señalado @thomleo, esto puede causar problemas con la recolección de basura. La solución propuesta se presenta en http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/ y se parece a

import weakref 

class Foo(object): 
    def __init__(self): 
     self.text = "Hello World" 
     self.bar = Bar(self) 

class Bar(object): 
    def __init__(self, parent): 
     self.parent = weakref.ref(parent) # <= garbage-collector safe! 
     self.newText = parent.text 

foo = Foo() 
+0

Gracias, esto funciona. El único problema que puedo ver con eso es que cuando intento acceder a muchos objetos, haré una llamada a 'parent.parent.parent.etc'. ¿Hay una manera más clara de hacer esto? –

+3

Si no me equivoco, también hay un problema importante con eso. Cuando intentas hacer '' del foo'' no necesariamente lo destruirá ya que todavía existe una referencia en el atributo '' .parent'' de '' Bar'' que contiene ... –

+0

@MichaelMcClenaghan, en ese caso, puede iterar varias veces en lugar de deletrearlo manualmente. Por supuesto, eso depende de la estructura ... – batbrat

4

es posible conseguir el objeto, por ejemplo Foo, que contiene otro objeto, Bar, desde dentro de la propia barra?

No "automáticamente", porque el lenguaje no está construido así, y en particular, el lenguaje está construido de tal manera que no hay forma de garantizar que exista Foo.

Dicho esto, siempre puede hacerlo explícitamente. Los atributos, como cualquier otro identificador en Python, son solo nombres, no espacio de almacenamiento para los datos; así que nada le impide dejar que la instancia de Bar tenga un atributo foo asignado manualmente que sea una instancia de Foo, y viceversa al mismo tiempo.

-3

Qué acerca del uso de la herencia:

class Bar(object): 
    def __init__(self): 
     self.newText = self.text 

class Foo(Bar): 
    def __init__(self): 
     self.txt = 'Hello World' 
     Bar.__init__(self) 

foo = Foo() 
print foo.newText 
Cuestiones relacionadas