1

我有一堂课A。在__init__一个实例的方法期间A

我创建了以下两个类实例BC

b = B()
c = C()

一切就绪后,我需要在 的方法中调用B的方法C

例子:

触发:

b.call_c()

做:

def call_c(self):
    parent.c.a_method_of_c()

我需要做什么来实现这个结构?

4

3 回答 3

3

您需要传递 ofselfctoB()以便它可以了解其他对象。

于 2012-12-29T22:45:15.997 回答
1

我需要在 的方法中调用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类对象的方法的例子Astr(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
于 2012-12-29T23:22:54.723 回答
1

如果您将 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 实现bc属性的必要性。

如果 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 本身中处理,但如果这些对象和关系在框架中持久化或复制,则可能无法处理)。

于 2012-12-29T23:42:55.223 回答