Python中的菱形问题:从所有父类调用方法
很多人都问这个问题,但几乎所有人都给出了我已经在应用的相同解决方案 所以我有类Python中的菱形问题:从所有父类调用方法,python,django,python-3.x,oop,Python,Django,Python 3.x,Oop,很多人都问这个问题,但几乎所有人都给出了我已经在应用的相同解决方案 所以我有类TestCase,B,C,D,E。类C和D继承类B和类E继承两个C和D。类B继承TestCase 当我运行代码时,类E仅使用类C的方法运行,并且一直忽略D。现在我的课程是这样的: class GenericAuthClass(TestCase): def setUp(self): """Create a dummy user for the purpose of testing."""
TestCase
,B
,C
,D
,E
。类C
和D
继承类B
和类E
继承两个C
和D
。类B
继承TestCase
当我运行代码时,类E
仅使用类C
的方法运行,并且一直忽略D
。现在我的课程是这样的:
class GenericAuthClass(TestCase):
def setUp(self):
"""Create a dummy user for the purpose of testing."""
# set some objects and variabels
def _get_authenticated_api_client(self):
pass
class TokenAuthTests(GenericAuthClass):
def _get_authenticated_api_client(self):
"""Get token recieved on login."""
super()._get_authenticated_api_client()
# make object
return object
class BasicAuthTests(GenericAuthClass):
def _get_authenticated_api_client(self):
"""Get token recieved on login."""
super()._get_authenticated_api_client()
# make object
return object
class ClientTestCase(BasicAuthTests, TokenAuthTests):
def dothis(self):
return self._get_authenticated_api_client()
如何调用C
中的方法(同名)和E
中的D
,就像C++
中的菱形问题一样?到目前为止,当我使用self.method()
从E
调用某个方法时,它只从C
调用该方法,而忽略了D
中的相同方法,而我认为它应该同时调用这两个方法
请注意,该方法在类E
中不存在,我的代码现在可以正常工作,没有错误,但只从C
调用该方法
这似乎主要是一个Python问题,但将Django标记为TestCase
类可能与此有关。这样说是正确的
您必须使用公共基类之类的东西来终止super
调用链
这意味着您需要编写自己的基类,该基类介于B
和C
和TestCase
之间,通过实现附加方法,然后不将任何调用委托给其父级,从而结束super
链:
from django.test import TestCase
class MyTestBase(TestCase):
def method1(self, arg):
pass
def method2(self, arg1, arg2):
pass
class B(MyTestBase):
def method1(self, arg):
super().method1(arg)
...
def method2(self, arg1, arg2):
super().method2(arg1, arg2)
...
class C(MyTestBase):
def method1(self, arg):
super().method1(arg)
...
def method2(self, arg1, arg2):
super().method2(arg1, arg2)
...
class D(B, C):
pass
你能提供完整的回溯和错误发生的线路吗?(可能是在创建
D
B
或C
对象的地方)我添加了完整的堆栈跟踪。关于我在哪里创作?我没有创建一个实例,django基本上是这样做的。你可以找到这方面的信息。基本上所有的TestCase
子类都是先运行的。看起来你的\uuuu init\uuuu
方法与django
所期望的任何接口都不匹配。无论如何,您不应该需要\uuuu init\uuu
方法,因为您实际上没有在这些方法中执行任何操作。在您的实际代码中,除了调用其父\uuuu init\uuu
方法之外,这些\uuu init\uuu
方法中还有什么吗?如果没有,您可以删除它们,并且将自动使用父方法。我在尝试修复问题时添加了这些方法,正如我在问题中提到的,在我的类D
中,我调用了一个特定的方法,它不存在于D
中,但存在于B
和C
。当我调试时,我发现该方法是为类B
调用的,并且代码的工作方式与D(B)
类类似,而不是为类C
调用的。它是多重继承,所以它应该在两个不同的实例中为两个类调用它。有点像C++
中的菱形问题。简而言之,问题是,类D(B,C)
的行为类似于类D(B)
。这需要super().method(一些,参数)
在B.method
中。基本上,D
将向上移动MRO(方法解析顺序),找到具有该名称的方法的第一个父类,并使用该方法。该方法可以使用super
调用MRO上的其他方法,但不会自动执行。嗨!我采用了你的方法,但问题还是一样。当我在D
中调用self.method1()
时,它从B
调用了method1()
,但没有从C
调用method1
。而我想两者都被调用。你能在你的问题中添加你正在使用的代码吗?另外,我的示例中的代码没有正确的self
,您可能会仔细检查代码。