Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-从另一个子类调用函数的子类_Python_Class_Design Patterns_Multiple Inheritance - Fatal编程技术网

Python-从另一个子类调用函数的子类

Python-从另一个子类调用函数的子类,python,class,design-patterns,multiple-inheritance,Python,Class,Design Patterns,Multiple Inheritance,我有一个相当大的类,我想把它分解成更小的类,每个类处理整个系统的一个部分。所以每个孩子只关心整体的一个方面 这些子类中的每一个仍然需要相互通信。 例如,“数据访问”创建绘图控制器需要访问的字典。 然后绘制控制器需要更新主GUI控制器上的内容。但是这些孩子有各种更多的交流功能 我如何做到这一点 我读过,但我不知道怎么做 最接近我的是以下代码: class A: def __init__(self): self.myself = 'ClassA' def meth

我有一个相当大的类,我想把它分解成更小的类,每个类处理整个系统的一个部分。所以每个孩子只关心整体的一个方面

这些子类中的每一个仍然需要相互通信。 例如,“数据访问”创建绘图控制器需要访问的字典。 然后绘制控制器需要更新主GUI控制器上的内容。但是这些孩子有各种更多的交流功能

我如何做到这一点

我读过,但我不知道怎么做

最接近我的是以下代码:

class A:
    def __init__(self):
        self.myself = 'ClassA'

    def method_ONE_from_class_A(self, caller):
        print(f"I am method ONE from {self.myself} called by {caller}")
        self.method_ONE_from_class_B(self.myself)

    def method_TWO_from_class_A(self, caller):
        print(f"I am method TWO from {self.myself} called by {caller}")
        self.method_TWO_from_class_B(self.myself)


class B:
    def __init__(self):
        self.me = 'ClassB'

    def method_ONE_from_class_B(self, caller):
        print(f"I am method ONE from {self.me} called by {caller}")
        self.method_TWO_from_class_A(self.me)

    def method_TWO_from_class_B(self, caller):
        print(f"I am method TWO from {self.me} called by {caller}")


class C(A, B):

    def __init__(self):
        A.__init__(self)
        B.__init__(self)

    def children_start_talking(self):
        self.method_ONE_from_class_A('Big Poppa')


poppa = C()
poppa.children_start_talking()
正确的结果是:

I am method ONE from ClassA called by Big Poppa
I am method ONE from ClassB called by ClassA
I am method TWO from ClassA called by ClassB
I am method TWO from ClassB called by ClassA
但是。。。即使类B和类A正确地调用了其他子类的函数,它们实际上也找不到它们的声明。当我输入代码时,我也没有“看到”它们,这既让人沮丧又让人担心我可能做错了什么

有没有一个好的方法来实现这一点?或者这真的是个坏主意

编辑:Python 3.7,如果它有任何不同。

继承 当打破这样的类层次结构时,我们称之为“mixin”的单个“部分”类将只“看到”直接在它们和它们的基类上声明的内容。在您的示例中,当编写类A时,它对类B一无所知—您作为作者,可以知道类B中的方法将出现,因为类A中的方法将仅从类C调用,而类C继承了这两个类

你的编程工具,包括IDE,不能知道这一点。(您应该比编程助手更了解这一点,这是一条旁道)。如果运行,它会工作,但这是一个糟糕的设计

如果所有方法都要直接出现在最终类的一个实例上,那么所有方法都必须“出现”在一个超类中——您甚至可以在不同的文件中编写独立的子类,然后是一个继承所有方法的子类:

来自abc导入抽象方法,abc
班级基数(ABC):
@抽象方法
def方法_A_1(自身):
通过
@抽象方法
def方法_A_2(自身):
通过
@抽象方法
def方法_B_1(自身):
通过
A类(基本类):
定义初始化(self,*args,**kwargs):
#pop从“kwargs”中使用命名参数
...
super()
#此调用确保调用所有基中的u u init__;
#因为Python在多重继承上线性化了基类
def方法_A_1(自身):
...
def方法_A_2(自身):
...
B类(基本类):
定义初始化(self,*args,**kwargs):
#pop从“kwargs”中使用命名参数
...
super()
#此调用确保调用所有基中的u u init__;
#因为Python在多重继承上线性化了基类
def方法_B_1(自身):
...
...
丙类(甲、乙类):
通过
(ABC和abstractmethod有点甜——它们会起作用,但这种设计没有它们也能起作用——因为它们的存在有助于查看代码的人了解发生了什么,并且如果您每一次错误地创建一个不完整基类的实例,就会引发早期的运行时错误)

混合成的 这是可行的,但是如果您的方法实际上是用于完全不同的域,那么 对于多重继承,您应该尝试使用

如果不是自然产生的,就不需要多重继承

在这种情况下,您将实例化驱动shell类的
\uuuu init\uuuu
上不同域的类的对象,并将其自身的实例传递给这些子类,这些子类将保留对它的引用(例如,在self.parent属性中)。很可能你的IDE仍然不知道你在说什么,但你会有一个更理智的设计


类父级:
定义初始化(自):
self.a_域=a(self)
self.b_域=b(self)
A类:
定义初始化(自身,父级):
self.parent=parent
#无需调用任何“super…init”,这称为
#作为父类初始化的一部分
def方法_A_1(自身):
...
def方法_A_2(自身):
...
B类:
定义初始化(自身,父级):
self.parent=parent
def方法_B_1(自身):
#需要来自“A”域的结果:
a_值=self.parent.a_domain.method_a_1()
...
本例使用基本的语言功能,但如果您决定 要在一个复杂的应用程序中使用它,您可以对它进行复杂化—有 接口模式,允许您交换使用的类 对于不同的域,在专门的子类中,等等。但通常
上面的模式是您需要的。

查找他们的声明是什么意思?我不明白你的解决方案出了什么问题。这意味着当我在B班写self的时候。它不显示除类B之外的任何其他类的函数。您可以在第二张图片中清楚地看到,它显示了该函数的“未解析属性引用”,该函数存在于类A中。下面的图片显示它无法“查看”其他子类的方法。甚至认为它存在于那里,并且它正确地调用了它。为什么您认为self应该显示其他类方法?您是打算继承这些类,还是应该包含彼此的实例?第一个模式是关于协作对象的高级建模。好的但你想把什么遗产放在那里?请记住,继承是一种关系,看起来您在这里使用了错误的工具。非常感谢您的详细回答。遗产部分我理解。基本上我缺少的是基类,它包含其他子类可能调用的所有子方法。合成部分可能就是我在中的部分