【有书共读01】《python学习手册》读书笔记十九

第六部分 类和oop

第25章 OOP:宏伟蓝图
本章学习目标:
1.对oop进行抽象的学习,先看一下蓝图
2.继承搜索

为何使用类:
类就是定义新种类的东西的方式,他反应了在程序领域中的真是对象。
继承,组合(包含其他对象,每个组建都可以写成类,定义自己的行为以及关系),
这些一般性的oop概念,适用于能够分解成一组对象的任何应用程序。
从程序设计的观点来看,类是python的程序组成单元,就像函数和模块一样;
类是封装逻辑和数据的另一种方式。
类也定义新的命名空间,很大程度上就像模块。
但是类有三个独特的功能:
多重实例:
类基本上就是产生对象的工厂。
每次调用一个类,就会产生一个独立命名空间的新对象。
每个由类产生的对象都能读取类的属性,并获得自己的命名空间来储存数据,这些数据对于每个对象来说都不同。
通过继承进行定制:
类也支持oop的继承的概念。
我们可以在类的外部重新定义其属性从而扩充这个类。
类可以建立命名空间的层次结构,而这种 层次结构 可以定义该结构中 类创建的对象 所使用的变量名。
运算符重载:
通过提供特定的协议方法,类可以定义对象来相应在内置类型上的几种运算。

概览oop;
对象(oo)python (p)
属性继承搜索:
表达式:object.attribute,我们对class语句产生的对象来使用这种方式时,这个表达式会在python中启动搜索,
搜索对象连接的树,来寻找attribute首次出现的对象。
上面的表达式翻译一下就是:
找出attribute首次出现的地方,先搜索object,然后是该对象之上的所有类,由下至上,由左至右。
取出属性只是简单的搜索 树 而已。
我们称这种搜索程序为继承,因为树中位置较低的对象继承了树中位置较高的对象拥有的属性。
当从下至上进行搜索树时,
连接至树中的 对象 就是树中所有上层对象所定义的所有属性的集合体,直到树的最顶端。
我们通过代码建立连接对象树,
而每次使用object.attribute表达式时,
python会在运行期间去“爬树”,来搜索属性。
如图所示:
包含了五个对象树,而对象都标识为变量,这些对象全都有相应的属性,可进行搜索。
此树把三个类的对象(C1,C2,C3)和两个实例对象(l1,l2)
连接至继承搜索树。
在python中,类和通过类产生的实例是两种不同的对象类型。
类树,底端有两个实例(l1和l2)在它上有个类(C1),顶端有两个超类(C2和C3)。
所在这些对象都是命名空间(变量的封装),
而继承就是由下至上搜索此树,来寻找属性名称出现的最低的地方。

类:
就是实例工厂。
类的属性提供了行为(数据和函数),所有丛类产生的实例都继承该类的属性。
实例:
代表程序领域中具体的元素。实例属性记录数据,而每个特定对象的数据都不同。

就搜索树来看,实例从它的类继承属性,而类是从搜索树中所有比他更上层的类中继承属性。
通常,我们把树中位置较高的类称为超类(C2,C3),
位置较低的类则称为子类(C1),
超类提供了所有子类共享的行为,但是因为搜索是由下而上的,
子类可能会在树中较低位置重新定义超类的变量名,从而覆盖超类定义的行为。

现在假设我们定义了如图的树:

然后写下:l2.w
这个代码会立即启用继承。
这是一个object.attribute表达式,于是会触发图中对树的搜索:
python会查看l2和其上的对象来搜索属性w。
以这个顺序搜索连接对象:l2,C1,C2,C3
找到首个w之后就会停止搜索(但如果找不到w,就会发生一个错误)。
这个树中,直到C3才找到w。
因此,l2从C3 继承 了属性w。
C1在树中较低的地方重新定义了属性x,相当于有效的取代其上C2中的版本。
这类重新定义就是oop中软件定制的重点。
通过重新定义和取代属性,C1有效的定制了它从超类中所继承的属性。

类和实例:
在python中,类和实例是两种不同的对象类型。
他们的主要差异在于:
类是一种产生实例的工厂。(可以制作很多实例)
而模块,特定的模块只能有一个实例(我们要重载模块一伙的其新代码),

操作角度来讲:
类通常都有函数,而实例有其他基本的数据项。
类的函数中使用这些数据。

类方法的调用:
l2.w引用是一个函数调用,
其实际含义就是:调用C3.w函数以处理l2。
就是说:l2.w()调用映射为C3.w(l2)调用,传入该实例做为继承的函数的第一个参数。

编写类树:
我们以class语句和类调用来构造一些树和对象。
a.每个class语句会生成一个新的类对象
b.每次类调用时,就会生成一个新的实例对象。
c.实例自动连接至创建了这些实例的类。
d.类连接至超类的方式是,将这些超类列在类头部的括号内。其从左至右的顺序会决定书中的次序。
例如,要建立如图所示的树:

class C2: ...       #这里省略了类里面的内容  
class C3: ...
class C1(C2,C3): ...

l1=C1()
l2=C1()

这个例子使用了多重继承。
就是说,这个类树中,类有一个以上的超类。
在python中,如果class语句中的小括号内有一个以上的超类,他们自左至右的次序会决定超类搜索的顺序。
把属性增加在这些对象上的代码:
属性通常在class语句中通过复制语句添加在类中,而不是嵌入在函数的def语句内。
属性通常是在类内,对传给函数的特殊参数(self),做赋值运算而添加在实例中的。
例如,类通过函数(class语句内有def语句编写而成)为实例提供行为。
因为这类嵌套的def会在类中对变量名进行赋值,实际效果就是把属性添加在了类对象之中,从而可以由实例和子类继承。
class C1(C2,C3):
    def setname(self,who):
        self.name=who

l1=C1()
l2=C1()
l1.setname('bob')
l2.setname('mel')
print(l1.name)         #bob
我们用另一个__init__方法来实现同样的功能
class C1(C2,C3):
    def __init__(self,who):
        self.name=who

l1=C1('bob')
l2=C1('mel')
print(l1.name)         #bob

实例见书P627


#笔记##读书笔记#
全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务