我有一堂课A
。在__init__
一个实例的方法期间A
;
我创建了以下两个类实例B
和C
:
b = B()
c = C()
一切就绪后,我需要在 的方法中调用B
的方法C
。
例子:
触发:
b.call_c()
做:
def call_c(self):
parent.c.a_method_of_c()
我需要做什么来实现这个结构?
我有一堂课A
。在__init__
一个实例的方法期间A
;
我创建了以下两个类实例B
和C
:
b = B()
c = C()
一切就绪后,我需要在 的方法中调用B
的方法C
。
例子:
触发:
b.call_c()
做:
def call_c(self):
parent.c.a_method_of_c()
我需要做什么来实现这个结构?
您需要传递 ofself
或c
toB()
以便它可以了解其他对象。
我需要在 的方法中调用
B
来自 的方法C
。
基本上,如果方法不是类方法或静态方法,那么调用方法总是意味着您可以访问类的 ( c
) 对象C
。
看看这个例子:
#!python3
class B:
def __init__(self, value):
self.value = value
def __str__(self):
return 'class B object with the value ' + str(self.value)
class C:
def __init__(self, value):
self.value = value
def __str__(self):
return 'class C object with the value ' + str(self.value)
class A:
def __init__(self, value):
self.value = value
self.b = B(value * 2)
self.c = C(value * 3)
def __str__(self):
lst = ['class A object with the value ' + str(self.value),
' containing the ' + self.b.__str__(),
' containing also the ' + str(self.c),
]
return '\n'.join(lst)
a = A(1)
print(a)
print(a.b)
print(a.c)
这self.b.__str__()
是从类对象的方法调用B
类对象的方法的例子A
。str(self.c)
相同,只是通过函数间接调用str()
。
显示如下:
class A object with the value 1
containing the class B object with the value 2
containing also the class C object with the value 3
class B object with the value 2
class C object with the value 3
如果您将 A 对象作为父/容器对象同时传递给 B 和 C,则如下所示:
class A(object):
def __init__(self):
self.b = B(self)
self.c = C(self)
class B(object):
def __init__(self, parent):
self.parent = parent
def call_c(self):
self.parent.c.a_method_of_c()
class C(object):
def __init__(self, parent):
self.parent = parent
# whatever...
或者,您可以像这样将 C 实例传递给 B 的初始化程序:
class A(object):
def __init__(self):
self.c = C()
self.b = B(self.c)
class B(object):
def __init__(self, c):
self.cobj = c
def call_c(self):
self.cobj.a_method_of_c()
class C(object):
# whatever...
我更喜欢第二种方法,因为它消除了 B 和 C 对 A 的依赖,以及 A 实现b
和c
属性的必要性。
如果 B 和 C 必须相互调用方法,您仍然可以使用 A 来建立这些关联,但要保持 B 和 C 不知道 A:
class A(object):
def __init__(self):
self.b = B()
self.c = C()
self.b.cobj = self.c
self.c.bobj = self.b
class B(object):
def __init__(self, c):
self.cobj = None
def call_c(self):
if self.cobj is not None:
self.cobj.a_method_of_c()
else:
raise Exception("B instance not fully initialized")
class C(object):
# similar to B
一般来说,您的目标是尽量避免或至少最小化这些依赖关系——让父母了解孩子,但孩子不了解父母。或者一个容器知道它包含的对象,但包含的对象不知道它们的容器。一旦添加了循环引用(对父对象或容器对象的反向引用),事情就会以各种令人惊讶的方式变得丑陋。当其中一个链接被清除而不是反射链接时,关系可能会被破坏。或者循环关系中的垃圾收集可能会变得棘手(在 Python 本身中处理,但如果这些对象和关系在框架中持久化或复制,则可能无法处理)。