【问题标题】:multiple inheritance, TypeError: __init__() takes 2 positional arguments but 3 were given多重继承,TypeError: __init__() 接受 2 个位置参数,但给出了 3 个
【发布时间】:2020-12-15 14:21:37
【问题描述】:

我正在学习类的多重继承

class A(): 
    def __init__(self, a): 
        super().__init__() 
        self.a = a                                                                                                                                             

class B(): 
    def __init__(self, b): 
        super().__init__() 
        self.b = b 
         
class C(A, B): 
    def __init__(self, a, b, c): 
        super().__init__(a, b) 
        self.c = c 

C(1, 2, 3) 导致错误 TypeError: __init__() takes 2 positional arguments but 3 were given

希望能按A->B->C的顺序初始化,查了存在的相关问题还是卡住了

【问题讨论】:

    标签: python class inheritance


    【解决方案1】:

    如果您需要为特定的超类提供特定的参数,您需要明确地这样做:

    class A(): 
        def __init__(self, a): 
            self.a = a                                                                                                                                             
    
    class B(): 
        def __init__(self, b): 
            self.b = b 
             
    class C(A, B): 
        def __init__(self, a, b, c): 
            A.__init__(self, a) 
            B.__init__(self, b)
            self.c = c
    

    请注意,您也不能再在 AB 类中执行 super().__init__(),因为 super 实际上并没有调用它“写入”的类的超类,而是调用下一个类提高方法解析顺序。

    通常,这样的代码表明设计不佳/滥用子类。


    或者,您可以通过使用关键字参数来解决此问题:

    class A(): 
        def __init__(self, *, a, **kwargs):
            super().__init__(**kwargs)
            self.a = a
    
    class B(): 
        def __init__(self, *, b, **kwargs): 
            super().__init__(**kwargs)
            self.b = b 
    
    class C(A, B): 
        def __init__(self, a, b, c): 
            super().__init__(a=a, b=b)
            self.c = c
    

    【讨论】:

      【解决方案2】:

      让基类更灵活,让它们将额外的*args 传递给超级调用:

      class A(): 
          def __init__(self, a, *args): 
              super().__init__(*args) 
              self.a = a
              
      
      class B(): 
          def __init__(self, b, *args): 
              super().__init__(*args) 
              self.b = b 
            
      
      class C(A, B): 
          def __init__(self, a, b, c): 
              super().__init__(a, b) 
              self.c = c 
      
      >>> c = C(1,2,3)
      >>> c.a
      1
      >>> c.b
      2
      >>> c.c
      3
      

      为了不依赖mro,最好使用关键字参数:

      class A(): 
          def __init__(self, a=None, **kwargs): 
              super().__init__(**kwargs) 
              self.a = a
              
      
      class B(): 
          def __init__(self, b=None, **kwargs): 
              super().__init__(**kwargs) 
              self.b = b
            
      
      class C(A, B): 
          def __init__(self, a, b, c): 
              super().__init__(a=a, b=b) 
              self.c = c 
      

      现在,class C(B, A) 将按预期工作。

      【讨论】:

        猜你喜欢
        • 2020-04-19
        • 2017-02-18
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-13
        • 2018-03-07
        • 2019-12-07
        相关资源
        最近更新 更多