自动推断 object 是 parent object/class 的属性
Automatically infer that an object is an attribute of a parent object/class
像这样使用类时:
class Parent:
def __init__(self):
self.child = Child()
class Child:
def __init__(self):
print(self.parent) # error, I don't have any way to know my parent!
p = Parent()
当然是returns错误,因为Child
实例没有属性parent
,这是正常的。
一个解决方案就是像这样简单地定义 类:
class Parent:
def __init__(self):
self.child = Child(self)
class Child:
def __init__(self, parent):
self.parent = parent
print(self.parent) # now it's ok!
但是在我的代码中,我有很多 类,在实例化 child [=45 时,必须始终将 self
作为参数传递,这有点烦人=]s:
self.child = Child(self) # pass self so that this Child instance will know its parent
我更愿意保持简单:
self.child = Child() # can this Child instance know its parent without passing self?
有没有办法让 Python 自动推断 object 实际上是 parent object 的属性,而无需显式传递 self
? 如果是这样,如何获得 parent?
示例:在GUI编程中创建Button实例时,它是Panel的成员,它本身是Window的成员,等等。看来我们必须通过self
一直child任建设者。
注意:我想避免使用 inspect
,因为它的解决方案似乎比仅传递 self
.
更差
从技术上讲,您可以通过使用 inspect
模块遍历堆栈来做到这一点,如下所示:
>>> import inspect
>>>
>>> class Parent:
... def __init__(self):
... self.child = Child()
...
>>> class Child:
... def __init__(self):
... for frame in inspect.stack():
... if isinstance(frame[0].f_locals.get('self'), Parent):
... self.parent = frame[0].f_locals.get('self')
... break
...
>>> p = Parent()
>>>
>>> p.child.parent
<__main__.Parent object at 0x000001ED3901A310>
不过,由于 许多 原因,这很糟糕。理想情况下,您应该完全避免这样的循环引用,更不用说通过在调用堆栈中翻找来构建它们了。
您可以创建一个设置方法来实例化子项,而不是使用检查来动态确定调用者。
class Parent:
def __init__(self):
self.child = self.create_child(Child)
def create_child(self, cls, *args, **kwargs):
return cls(*args, parent=self, **kwargs)
如果这是您可能会在很多 class 中使用的东西,您也可以将它移到基础 class 中。
像这样使用类时:
class Parent:
def __init__(self):
self.child = Child()
class Child:
def __init__(self):
print(self.parent) # error, I don't have any way to know my parent!
p = Parent()
当然是returns错误,因为Child
实例没有属性parent
,这是正常的。
一个解决方案就是像这样简单地定义 类:
class Parent:
def __init__(self):
self.child = Child(self)
class Child:
def __init__(self, parent):
self.parent = parent
print(self.parent) # now it's ok!
但是在我的代码中,我有很多 类,在实例化 child [=45 时,必须始终将 self
作为参数传递,这有点烦人=]s:
self.child = Child(self) # pass self so that this Child instance will know its parent
我更愿意保持简单:
self.child = Child() # can this Child instance know its parent without passing self?
有没有办法让 Python 自动推断 object 实际上是 parent object 的属性,而无需显式传递 self
? 如果是这样,如何获得 parent?
示例:在GUI编程中创建Button实例时,它是Panel的成员,它本身是Window的成员,等等。看来我们必须通过self
一直child任建设者。
注意:我想避免使用 inspect
,因为它的解决方案似乎比仅传递 self
.
从技术上讲,您可以通过使用 inspect
模块遍历堆栈来做到这一点,如下所示:
>>> import inspect
>>>
>>> class Parent:
... def __init__(self):
... self.child = Child()
...
>>> class Child:
... def __init__(self):
... for frame in inspect.stack():
... if isinstance(frame[0].f_locals.get('self'), Parent):
... self.parent = frame[0].f_locals.get('self')
... break
...
>>> p = Parent()
>>>
>>> p.child.parent
<__main__.Parent object at 0x000001ED3901A310>
不过,由于 许多 原因,这很糟糕。理想情况下,您应该完全避免这样的循环引用,更不用说通过在调用堆栈中翻找来构建它们了。
您可以创建一个设置方法来实例化子项,而不是使用检查来动态确定调用者。
class Parent:
def __init__(self):
self.child = self.create_child(Child)
def create_child(self, cls, *args, **kwargs):
return cls(*args, parent=self, **kwargs)
如果这是您可能会在很多 class 中使用的东西,您也可以将它移到基础 class 中。