2012-05-28 7 views
18

Trong Python, có thể lấy đối tượng, nói Foo, có chứa một đối tượng khác, Bar, từ bên trong Bar không? Dưới đây là ví dụ về ý tôi làNhận đối tượng container/parent từ bên trong 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() 

Điều này có thể? Cảm ơn!

+2

Bạn đã có một lỗi đánh máy; trong 'Foo .__ init__',' self.bar = Foo() 'phải là' self.bar = Bar() '. Nếu không, bạn đã có một vòng lặp vô hạn (để tạo một Foo, trước tiên bạn phải tạo một Foo). –

+0

Cảm ơn, đã sửa! :) –

Trả lời

29

Vượt qua một tham chiếu đến đối tượng thanh, như vậy:

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: như chỉ ra bởi @thomleo, điều này có thể gây ra vấn đề với thu gom rác thải. Các giải pháp đề nghị được đặt ra tại http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/ và trông giống như

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

Cảm ơn, công trình này. Vấn đề duy nhất tôi có thể thấy với điều đó là, khi tôi đang cố truy cập nhiều đối tượng, tôi sẽ thực hiện cuộc gọi đến 'parent.parent.parent.etc'. Có cách nào để làm điều này không? –

+3

Nếu tôi không nhầm, đó cũng là một vấn đề lớn với điều đó. Khi bạn cố gắng thực hiện '' del foo'', nó sẽ không nhất thiết phá hủy nó như là một tham chiếu đến nó vẫn tồn tại trong thuộc tính '' .parent'' của '' Bar'' nó chứa ... –

+0

@MichaelMcClenaghan, trong trường hợp đó, bạn chỉ có thể lặp lại một số lần thay vì sửa lỗi chính tả theo cách thủ công. Tất nhiên, điều đó phụ thuộc vào cấu trúc ... – batbrat

4

là nó có thể để có được những đối tượng, nói Foo, có chứa một đối tượng, Bar, từ bên trong Bar bản thân?

Không "tự động", vì ngôn ngữ không được xây dựng như vậy và đặc biệt, ngôn ngữ được xây dựng sao cho không có cách nào đảm bảo rằng Foo tồn tại.

Điều đó nói rằng, bạn luôn có thể làm điều đó một cách rõ ràng. Các thuộc tính, giống như mọi định danh khác trong Python, chỉ là các tên, không phải là không gian lưu trữ cho dữ liệu; do đó, không có gì ngăn cản bạn cho phép cá thể Bar có thuộc tính được gán theo cách thủ công là thuộc tính Foo là 01ivà ngược lại cùng một lúc.

-3

gì về việc sử dụng thừa kế:

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