Python中的基本多态混淆

时间:2015-08-06 18:09:46

标签: python inheritance polymorphism

我正在阅读Python 3面向对象编程,并且其中一个例子让我感到有些困惑。它是ch。 3,p。 78:

class AudioFile:
    def __init__(self, filename):
        if not filename.endswith(self.ext):
            raise Exception("Invalid file format")
        self.filename = filename

class MP3File(AudioFile):
    ext = "mp3"
    def play(self):
        print("playing {} as mp3".format(self.filename))

所以MP3File继承自AudioFile。超级类AudioFile如何能够访问self.ext?例如,Java具有抽象类,因此无法保证AudioFile必须实例化/具有ext字段。更重要的是,我认为子类继承了超类中的所有信息,但是在另一个方向上没有信息流。

似乎我错了......

任何澄清都会很棒,

bclayman

2 个答案:

答案 0 :(得分:2)

理想情况下,int main () { Child a; // compile error Child b[7]; // compile error Child c(13); // OK } 应该是abc,因为它确实定义了字段(self.ext)。如果您尝试实例化:%s/\t/\&/g,则应该收到属性错误。

我认为你是对的..这个例子还不想进入abc。

答案 1 :(得分:1)

您说得对,无法保证AudioFile具有ext属性。如果您要直接实例化AudioFile,或者编写一个没有定义ext并实例化它的子类,那么尝试访问self.ext确实会失败。

因此,您可以将AudioFile视为一个抽象类,因为它依赖于其子类填充详细信息,以便AudioFile本身正常工作。但在Python中,这种抽象不是由语言编码的;你只需要记录人们必须编写定义ext的AudioFile的子类,如果他们不这样做,那么他们可能会遇到错误。 (abc模块可以处理其他一些抽象概念,但实际上它们通常也是通过文档约定来处理的。)

至于AudioFile如何在存在的情况下访问该属性。 。 。好吧,它在实例上访问它,而不是类。使用MP3File之类的内容实例化obj = MP3File()后,您就拥有了一个实例对象obj。对该对象执行obj.ext将返回其ext属性,或者,如果该实例没有自己的属性,它将在其类中查找此类属性(然后在其超类上查找向上)。每次尝试访问属性时,此属性查找都会动态发生;你没有,也不能预先宣布"将在何处找到属性(在实例,类或层次结构上的某个超类)。因此当AudioFile同时MP3File self.ext MP3File时,它会在self上找到该属性,因为MP3FileAudioFile的实例

如果这本书到目前为止没有解释任何一个,那么这个例子可能不是最好的。它有效,但它的工作原理对于具有不同OO语义的其他语言的用户来说并不明显。此外,即使您确实了解Python,在实际情况下,让文档告诉您如何使用ext至关重要(即,说"您必须将其子类化,并且您的子类必须定义id)。