2012-05-28 7 views
18

Czy w Pythonie można uzyskać obiekt, na przykład Foo, który zawiera inny obiekt, pasek, z poziomu samego paska? Oto przykład tego, co mam na myśli:Czy to możliwe? Dzięki!Uzyskiwanie obiektu kontener/obiekt nadrzędny z poziomu Pythona

+2

Masz literówkę; w 'Foo .__ init__',' self.bar = Foo() 'powinno być' self.bar = Bar() '. W przeciwnym razie masz nieskończoną pętlę (aby utworzyć Foo, musisz najpierw utworzyć Foo). –

+0

Dzięki, Naprawiono! :) –

Odpowiedz

29

Przepuścić odniesienie do obiektu bar, tak jak poniżej:

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

Edit: jak podkreślił @thomleo, może to spowodować problemy z zbierania śmieci. Proponowane rozwiązanie jest określone w http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/ i wygląda

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

Dzięki, to działa. Jedyny problem jaki widzę z tym, to gdy próbuję uzyskać dostęp do wielu obiektów, będę wywoływał 'parent.parent.parent.etc'. Czy jest to lepszy sposób na zrobienie tego? –

+3

Jeśli się nie mylę, jest to również poważny problem. Kiedy spróbujesz zrobić '' del foo'', to niekoniecznie zniszczy go jako odniesienie do niego nadal istnieje w atrybucie '' .parent'' 'Bar'' zawiera ... –

+0

@MichaelMcClenaghan, w takim przypadku możesz po prostu powtórzyć numer kilka razy zamiast ręcznie go wypisać. Oczywiście zależy to od struktury ... – batbrat

4

jest to możliwe, aby uzyskać obiekt, Foo powiedzieć, że zawiera inny obiekt, Bar, od wewnątrz samego Bar?

Not „automatycznie”, ponieważ język nie jest zbudowany tak, aw szczególności język jest zbudowany tak, że nie ma sposobu, aby zagwarantować, że Foo istnieje.

Powiedziawszy, możesz zawsze zrobić to jawnie. Atrybuty, podobnie jak każdy inny identyfikator w Pythonie, to tylko nazwy, a nie miejsce do przechowywania danych; więc nic nie stoi na przeszkodzie, aby instancja Bar miała ręcznie przypisany atrybut foo, który jest instancją Foo, i na odwrót w tym samym czasie.

-3

Co za pomocą dziedziczenia:

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 
Powiązane problemy