python对象-多态
调用不同的子类将会产生不同的行为,而无须明确知道这个子类实际上是什么。
比如,在一个可以播放音频文件的程序中,媒体播放器可能需要加载一个AudioFile对象然后play它,我们把一个play()的方法放在这个对象里,它负责解压或者提取音频,然后把音频引导到声卡或者扬声器,一个AudioFile行为可以如下这么简单:
audio_file.play()
然而,对于不同类型的文件,解压和提取音频文件的过程是很不一样的。.wav文件存储为压缩的音频,.mp3、.wma和.ogg文件都有不同的压缩算法。
我们可以使用多态和继承来让设计简单化。每种不同类型的文件都可以表示为一个AudioFile的不同子类,例如WavFile、MP3File。每一种都有一个play()方法。媒体播放器对象永远不需要知道它引用了AudioFile的哪一个子类,它只是调用play()方法然后多态地让对象去处理实际播放的细节。
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)) class WavFile(AudioFile):
ext = "wav"
def play(self):
print("playing {} as wav".format(self.filename)) class OggFile(AudioFile):
ext = "ogg"
def play(self):
print("playing {} as ogg".format(self.filename))
所有音频文件的检查确保了初始化的一个有效扩展,但是注意到,如何让父类的__init__方法取访问来自不同子类的ext变量,这就是多态的工作。如果文件并没有以正确的名字结尾,就会抛出一个异常。事实上,AudioFile没有存储ext变量的引用这一事实并不能阻止它在子类中访问。
每一个AudioFile子类会以不同的方式实现play()方法,媒体播放器可以使用完全相同的代码来播放文件,无论它是什么类型,它并不在乎使用AudioFile的哪一个子类。
>>> ogg = OggFile("myfile.ogg")
>>> ogg.play()
playing myfile.ogg as ogg
>>> mp3 = MP3File("myfile.mp3")
>>> mp3.play()
playing myfile.mp3 as mp3
>>> not_an_mp3 = MP3File("myfile.ogg")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "AudioFile.py", line 4, in __init__
raise Exception("Invalid file format")
Exception: Invalid file format
以上的例子展现了AudioFile.__init__方法在不知道哪一个子类在引用它的情况下,可以检查文件类型。
参考:
1、《Python3 面向对象编程》 [加]Dusty Philips 著
python对象-多态的更多相关文章
- python基础——多态与多态性
python基础--多态与多态性 1 多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 1. 序列类型有多种形态:字符串,列表,元组. 2. 动物有多种形态:人, ...
- Python 源码剖析(一)【python对象】
处于研究python内存释放问题,在阅读部分python源码,顺便记录下所得.(基于<python源码剖析>(v2.4.1)与 python源码(v2.7.6)) 先列下总结: ...
- python 对象和类
python中所有数据都是以对象形式存在.对象既包含数据(变量),也包含代码(函数),是某一类具体事物的特殊实例. 面向对象的三大特性为封装.继承和多态. 1.定义类 #定义空类 class Pers ...
- 探索Python的多态是怎么实现的
多态是指通过基类的指针或者引用,在运行时动态调用实际绑定对象函数的行为. 对于其他如C++的语言,多态是通过在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来 ...
- 《python解释器源码剖析》第1章--python对象初探
1.0 序 对象是python中最核心的一个概念,在python的世界中,一切都是对象,整数.字符串.甚至类型.整数类型.字符串类型,都是对象.换句话说,python中面向对象的理念观测的非常彻底,面 ...
- python之多态
python之多态 一.什么是多态? 同一种事物,有多种形态! class Animal: #同一类事物:动物 def talk(self): pass class Cat(Animal): #动物的 ...
- python征程3.0(python对象)
1.python使用对象模型来存储数据.构造任何类型的值都是一个对象.”尽管python被当成一种面向对象的脚本的编程语言“,但你完全能够写出不使用任何类和实例的脚本. python对象都拥有三个特性 ...
- python 对象
python 对象 在python中,对象就是为C中的结构体在堆上申请的一块内存,一般来说,对象是不能被静态初始化的,并且不能再栈空间上生存.本文主要对Python的基本数据类型做简单的介绍. PyO ...
- java中对象多态时成员变量,普通成员函数及静态成员函数的调用情况
/* 样例1: class Parent{ int num = 3; } class Child extends Parent{ int num = 4; } */ /* 样例2: class Par ...
随机推荐
- Atcoder Beginner Contest 121 D - XOR World(区间异或和)
题目链接:https://atcoder.jp/contests/abc121/tasks/abc121_d 题目很裸(Atcoder好像都比较裸 就给一个区间求异或和 n到1e12 肯定不能O(n) ...
- 2.23日刷数论题后总结(题目整理自SCUT
第一道:Rightmost digit 求N^N次最后一个数字 快速幂mod10咯 代码如下: #include <cstdio> #define ll long long using n ...
- codeforces618B
Guess the Permutation CodeForces - 618B Bob has a permutation of integers from 1 to n. Denote this p ...
- nginx POSTREAD阶段模块
L:50 Realip模块 需要将--with-http_realip_model 编译进Nginx 因为nginx有可能有反向代理 获取到的客户端ip就不是原用户IP了 X-Forwarded-Fo ...
- BZOJ1012 最大数maxnumber
单调栈的妙处!! 刚看到这题差点写个splay..但是后来看到询问范围的只是后L个数,因为当有一个数新进来且大于之前的数时,那之前的数全都没有用了,满足这种性质的序列可用单调栈维护 栈维护下标(因为要 ...
- python中的logging模块学习
Python的logging模块 Logging的基本信息: l 默认的情况下python的logging模块打印到控制台,只显示大于等于warning级别的日志 l 日志级别:critical ...
- IOI2008 island
题目链接:[IOI2008]Island 题目大意:求基环树直径(由于题目的意思其实是类似于每个点只有一个出度,所以在每个联通块中点数和边数应该是相同的,这就是一棵基环树,所以题目给出的图就是一个基环 ...
- python_getpass 模块的使用
可以实现输入用户密码的时候隐藏输入显示.更加安全. 默认自带Password: 的提示 如果自己指定提示内容就用自己的替换默认 import getpass passwd = getpass.getp ...
- MT【295】线段比的仿射变换
已知$F_1,F_2$分别为椭圆$\dfrac{x^2}{4}+\dfrac{y^2}{3}=1$的左右焦点.$A,B,C$是椭圆上$x$轴上方的三点,且$AF_1//BO//CF_2$,则$\dfr ...
- flowable6.4.1+springboot使用dmn
resources/dmn/strings_1.dmn <?xml version="1.0" encoding="UTF-8"?> <def ...