【问题标题】:Initializing superclasses Python3初始化超类 Python
【发布时间】:2021-05-22 15:05:54
【问题描述】:

我试图了解在 python 中使用继承时何时初始化超类。最初我认为只需声明一个继承自超类的类,例如。 class my_class(superclass):, 将使所有超类的属性和方法对子类可用。这对于来自 Java 的人来说是有意义的。然后我读到 Python 强制我们在我们可以在子类中实现它们之前初始化超类,或者使用超类。init() 或 super().init() .然后我遇到了这段代码,我没有初始化父类,但是 Python 让我可以在没有初始化父类的情况下从超类访问 self.queue 属性。我阅读了 Python 文档,有时我认为我知道它们的含义而其他一些我不知道。谁能解释一下我们什么时候必须在我们的子类中初始化超类?

class QueueError(IndexError):
pass

class Queue:
    def __init__(self):
       self.queue = []
    def put(self,elem):
       self.queue.insert(0,elem)
    def get(self):
        if len(self.queue) > 0:
            elem = self.queue[-1]
            del self.queue[-1]
            return elem
        else:
            raise QueueError

    class SuperQueue(Queue):
    def isempty(self):
        if not self.queue:
            return True
        else:
            return False

que = SuperQueue()
que.put(1)
que.put("dog")
que.put(False)
for i in range(4):
    if not que.isempty():
        print(que.get())
    else:
        print("Queue empty")

【问题讨论】:

    标签: python-3.x inheritance initialization


    【解决方案1】:

    一般来说,如果你在你的子类中重写__init__,你应该只调用super __init__方法。如果您扩展超类,这是必要的。但是如果你想覆盖整个__init__,你也可以省略super调用。

    示例:

    你有一个类A,它有一个属性value1。 现在你需要第二个属性,所以你用B子类化A并覆盖你调用超类(A)的__init__,所以A可以设置value1B你不能设置value2.
    但是现在您需要C 中的一些其他属性,但需要与A 中相同的方法。所以你可以完全覆盖__init__ 并省略对A 的超级调用。

    class A:
        def __init__(self, value1):
            print("Initialize A")
            self.value1 = value1
    
    
    class B(A):
        def __init__(self, value1, value2):
            super().__init__(value1)
            print("Initialize B")
            self.value2 = value2
    
    
    class C(A):
        def __init__(self, value3):
            print("Initialize C")
            self.value3 = value3
    
    
    a = A("foo")
    b = B("foo", "bar")
    c = C("baz")
    
    print(a.value1)
    print(b.value1, b.value2)
    print(c.value3)
    print(c.value1)
    

    输出

    $ python main.py
    Initialize A
    Initialize A
    Initialize B
    Initialize C
    foo
    foo bar
    baz
    Traceback (most recent call last):
      File "main.py", line 27, in <module>
        print(c.value1)
    AttributeError: 'C' object has no attribute 'value1'
    

    你可以看到C没有用value1初始化,因为C没有调用A__init__

    【讨论】:

    • 换句话说,我们可以说子类自动继承了超类的所有特征。但是如果一个子类试图访问超类的特征,它将产生一个 AttributeError 异常,只有当我们覆盖超类 init 时。现在我看到了 super().__init__() 正在做什么,它基本上是在子类中覆盖了超类 init 中定义的超类特征时,它使子类可以访问超类的特征。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2022-01-23
    • 2016-12-30
    • 2019-02-07
    相关资源
    最近更新 更多