Python 多重继承只适用于一个父类的方法,但从两个父类调用方法

Python multiple inheritance only working for one parent's method but calling method from both parents

我有一个 Python/OOP 问题。
你们都熟悉 C++ 中的菱形问题吧?这是类似的东西。
我有以下 classes

class BaseAuth(TestCase):

    def setUp(self):
        # create dummy user and client, removing code of that for simplicity.
        self.user.save()
        self.client.save()

    def _get_authenticated_api_client(self):
        pass

class TokenAuthTests(BaseAuth):

    def _get_authenticated_api_client(self):
        super()._get_authenticated_api_client()
        print("I AM IN TOKEN AUTH")
        api_client = APIClient()
        # do stuff with api_client
        return api_client

class BasicAuthTests(BaseAuth):

    def _get_authenticated_api_client(self):
        super()._get_authenticated_api_client()
        print("I AM IN BASIC AUTH")
        api_client = APIClient()
        # do stuff with api client
        return api_client

class ClientTestCase(BasicAuthTests, TokenAuthTests):

    def test_get_login_response(self):
        api_client = self._get_authenticated_api_client()
        # login test code

    def test_get_clients(self):
        api_client = self._get_authenticated_api_client()
        # get client test code

    def test_get_client_by_id(self):
        api_client = self._get_authenticated_api_client()
        # get client by id test code

    def test_update_client_by_id(self):
        api_client = self._get_authenticated_api_client()
        # update client test code

    def test_add_client(self):
        api_client = self._get_authenticated_api_client()
        # add client test code

    def test_delete_client_by_id(self):
        api_client = self._get_authenticated_api_client()
        # delete client test code

现在,当我 运行 代码时,我可以看到打印出来的是:

I AM IN TOKEN AUTH
I AM IN BASIC AUTH
.I AM IN TOKEN AUTH
I AM IN BASIC AUTH
.I AM IN TOKEN AUTH
I AM IN BASIC AUTH
.I AM IN TOKEN AUTH
I AM IN BASIC AUTH
.I AM IN TOKEN AUTH
I AM IN BASIC AUTH
.I AM IN TOKEN AUTH
I AM IN BASIC AUTH

但是,如果我从功能的角度来看,测试 运行 仅适用于 BasicAuthTests。我怎么知道的?

1.测试运行s个数是6,本来应该是126每个父class.

2. 如果我将 BasicAuthTests 中的 _get_authenticated_api_client() 函数更改为错误的 return 类型,代码会崩溃,但如果我在 TokenAuthTests 中更改它,则什么也不会发生,这意味着 TokenAuthTests 没有做任何事情,但它的打印语句在工作,这意味着函数被调用。

这太令人困惑了,有人可以帮忙吗?
我的最终目标是 运行 为每个父 class 返回的 api_client.

这 6 个测试

HERE IS MUST MENTION THAT, THE CODE RUNS FINE. AND THE TEST WORK ALRIGHT IF I RUN THEM SEPARATELY. I AM TRYING TO SIMPLIFY THE CODE AND REMOVE ALL THE REPETITION, THAT'S WHY I AM KIND TO TRYING TO MERGE THEM INTO ONE FILE.

您被我们的 MRO 困住了。 虽然 Python 支持 Diamond Inheritance,但在变量赋值时你会卡住。

多亏了 Diamond Inheritance,我们现在 _get_authenticated_api_client 都将被调用。在分配时,_get_authenticated_api_client returns 取决于您通过 classes 的顺序。

在你的例子中,只有 6 个测试 运行 因为你只有一个 class,具有 6 个测试功能。

您打算 运行 使用不同的 auth 方法进行完全相同的测试。 一种简单的方法是:

class ClientMixinCase: #Do not Inherit from "TestCase"
    #... Declare you tests here

class ClientWithTokenAuthTestCase(ClientMixinCase,TokenAuthTests):
    pass

class ClientWithBasicAuthTestCase(ClientMixinCase,BasicAuthTests):
    pass

所以我用不同的方法解决了这个问题。

我们可以做的是,我们可以在父 class 中声明所有测试,并在子 classes.

中声明函数 _get_authenticated_api_client 但是我们如何在父 class 中使用子 class 的函数呢?

当父 class 继承 TestCase 并且将成为第一个 class 时,测试将从 运行 开始,它将崩溃,因为它没有 _get_authenticated_api_client 功能。

为了避免这种情况,我们所做的是将父 class 包装在另一个 class 中,这样 class 就不会被视为 class 而是父 class.

但是当我们从包装的父 TestCase 继承 class 继承我们的子 classes 时,它将被视为 class 并且它的测试将是 运行 但是在那一点 _get_authenticated_api_client 函数将在 child 中声明。 这是代码

class WrapperTestClass:

    class ClientTestCase(TestCase):

        # all the tests and setup function

class TokenAuthTests(WrapperTestClass.ClientTestCase):

    def get_authenticated_api_client(self):
        # function that returns api_client

class BasicAuthTests(WrapperTestClass.ClientTestCase):

    def get_authenticated_api_client(self):
        # function that returns api_client