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