在 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()
这可能吗?谢谢!
传递对 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()
是否有可能从 Bar 本身获取包含另一个对象 Bar 的对象(例如 Foo)?
不是“自动”,因为语言不是这样构建的,特别是,语言的构建使得无法保证 Foo 存在。
也就是说,你总是可以明确地做到这一点。与 Python 中的所有其他标识符一样,属性只是名称,而不是数据的存储空间;因此,没有什么可以阻止您让 Bar 实例具有手动分配的
foo
属性,该属性是 Foo 实例,反之亦然。
是的,这是可能的。即使在创建对象时没有传递容器引用,即如果您的对象是类属性。 你的对象需要实现描述符协议(有一个
__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.
这对我有用:
家长:
import child
obj_1 = 25 # an object that both parent and child can access
def startup(): # any startup function
global obj_1
child.ref( obj_1 ) # send the shared object to the child
...
孩子:
obj_1 = 0 # initual value will be overwritten
def ref(shared_obj): # receive a reference to the shared object
global obj_1 # shared object is global in the child, optional
obj_1 = shared_obj # set obj_1 in the child to be obj_1 in the parent
可以通过检查
import inspect
class Foo(object):
def __init__(self):
self.text = "Hello World"
self.bar = Bar()
class Bar(object):
def __init__(self):
parentFrameInfo = inspect.stack()[1]
parentLocalContext = parentFrameInfo.frame.f_locals
# in parent context (__init__ of Foo) object instance is in variable 'self'
foo = parentLocalContext["self"]
self.newText = foo.text #This is what I want to do,
#access the properties of the container object
foo = Foo()
print(foo.text)
print(foo.bar.newText)
但是您需要在构造函数中的
self.text
之前声明 self.bar
。如果不这样做,当调用 Bar()
时,self.text 不会被定义
无论如何,只有当您有真正的特定约束时才应该执行此操作(例如,为了向后兼容,
Foo
构造函数 API 无法更改)。添加 Bar
构造函数 Foo
实例是一个更好的解决方案。
使用继承怎么样:
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