在Python中,是否有可能从Bar内部获取包含另一个对象Bar的对象,比如说Foo?这是我的意思的一个例子
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()
这可能吗?谢谢!
答案 0 :(得分:38)
传递对Bar对象的引用,如下所示:
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()
如@thomleo所指出的编辑,这可能会导致垃圾回收问题。建议的解决方案在http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/列出,看起来像
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()
答案 1 :(得分:5)
是否有可能从Bar内部获取包含另一个对象Bar的对象,比如说Foo?
不是“自动”,因为语言不是那样构建的,特别是构建语言使得无法保证Foo存在。
那就是说,你总是可以明确地做到这一点。与Python中的每个其他标识符一样,属性只是名称,而不是数据的存储空间;所以没有什么能阻止你让Bar实例拥有一个手动分配的foo
属性作为Foo实例,反之亦然。
答案 2 :(得分:0)
是的,有可能。即使没有在创建对象时传递容器引用,即对象是否为类属性。
您的对象需要实现描述符协议(具有__get__()
):
class ChildName(SimpleNamespace):
def __get__(self, instance, owner):
# instance is our parent
return f'I am {self.name}, my parent is {instance.name}.'
class ChildDiff(SimpleNamespace):
@property
def diff(self):
return self.born - self.parent.born
def age_diff(self):
return f'I am {self.diff} years older than {self.parent.name}.'
def __get__(self, instance, owner):
self.parent = instance # XXX: weakref?
return self # expose object to be able call age_diff() etc.
class Parent(SimpleNamespace):
child_name = ChildName(name='Bar')
child_diff = ChildDiff(born=42)
parent = Parent(name='Foo', born=23)
print(parent.child_name) # ... I am Bar, my parent is Foo.
print(parent.child_diff.age_diff()) # ... I am 19 years older than Foo.
答案 3 :(得分:-3)
使用继承怎么样:
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