从python中获取容器/父对象

时间:2012-05-28 23:52:06

标签: python class object containers

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

这可能吗?谢谢!

4 个答案:

答案 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