当前位置: 首页 > 面试题库 >

python3中具有不同签名的多重继承

卫烨烁
2023-03-14
问题内容

我有三个类:ABC

C继承自AB(按此顺序)。的构造特征AB不同。如何调用__init__两个父类的方法?

我在代码中的努力:

class A(object):
    def __init__(self, a, b):
        super(A, self).__init__()
        print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))

class B(object):
    def __init__(self, q):
        super(B, self).__init__()
        print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))

class C(A, B):
    def __init__(self):
        super(A, self).__init__(1, 2)
        super(B, self).__init__(3)

c = C()

产生错误:

Traceback (most recent call last):
  File "test.py", line 16, in <module>
    c = C()
  File "test.py", line 13, in __init__
    super(A, self).__init__(1, 2)
TypeError: __init__() takes 2 positional arguments but 3 were given

我发现此资源用不同的参数集解释了多重继承,但他们建议对所有参数使用*args**kwargs。我觉得这很丑陋,因为我无法从子类的构造函数调用中看到将哪些参数传递给父类。


问题答案:

千万 不能* 使用super(baseclass, ...),除非你知道自己在做什么。第一个参数super()告诉它寻找下一个要使用的方法时要
跳过的 类。例如,super(A, ...)将查看MRO,找到A,然后开始 在下一个 基类 而不是
本身__init__上寻找。因为,MRO是,所以会找到。

***A``C``(C, A, B, object)``super(A, self).__init__``B.__init__

对于这些情况,你不希望使用合作继承,而是直接引用A.__init__B.__init__替代。super()仅在您所调用的方法具有
相同签名时使用, 否则将使用*args和吞下不受支持的参数**vargs。在这种情况下,只super(C, self).__init__()需要一个调用,MRO顺序中的下一个类将负责该调用的链接。

换种说法:使用时super(),您无法知道MRO中的下一个类,因此该类更好地支持传递给它的参数。如果不是这种情况,请 不要 使用super()

__init__直接调用基本方法:

class A(object):
    def __init__(self, a, b):
        print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))

class B(object):
    def __init__(self, q):
        print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))

class C(A, B):
    def __init__(self):
        # Unbound functions, so pass in self explicitly
        A.__init__(self, 1, 2)
        B.__init__(self, 3)

使用合作社super()

class A(object):
    def __init__(self, a=None, b=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))

class B(object):
    def __init__(self, q=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))

class C(A, B):
    def __init__(self):
        super().__init__(a=1, b=2, q=3)


 类似资料:
  • 问题内容: 使用以下代码示例,可以使用它,还是必须对其进行调用并显式? 问题答案: 只会解析给定方法的单个类类型,因此,如果您要从多个类继承,并想在两个类中都调用该方法,则需要显式地进行操作。 即

  • 问题内容: 我有一个超类的方法: 在其子类之一中,我想执行以下操作: 但这是行不通的。问题是我有一个超类的引用,并且我想只在其中一个子类中调用此方法。 问题答案: 您不能在重写方法中更改类型参数的数量。对于您的情况,返回类型显然会覆盖失败。但是,即使返回类型相同,您的方法仍然不会被覆盖等效,因为您应该覆盖的方法中的类型参数更少。 从JLS- 方法签名 : 如果两个方法具有相同的名称和参数类型,则它

  • 问题内容: 我发布了我的APP,然后为了测试它,在手机上安装了APK。使用导出的APK,Facebook无法正常工作(错误的哈希),但是使用开发人员bin.ed apk可以正常工作。 有人可以告诉我怎么回事吗?密钥哈希为何不同?(第二次,日食更新第一次更改了它)。 也 由于我已经将APK上传到市场并发布了(现在尚未发布,非常烦人)。另外,我已经在本地删除了APK,因此我无法找到密钥哈希,也无法从市

  • 我试图在C++中创建一个,作为键,泛型方法作为,但我不知道这是否可能。我想做这样的事情: 这可能吗?如果是,我如何实现这一点?

  • 我在看一些基本的向量库,这个类有两个的签名,但是我不能理解这两者之间的区别。 > 两者使用时外观如何? 为什么一个使用而另一个仅使用? 谢谢你!

  • 我是流口水的新手,熟悉使用扩展关键字来继承规则。问题是有没有办法继承多个规则?这类似于在java类上使用多个接口。这是一个我希望它如何工作的示例,但我在规则3上遇到错误: