天天看点

Learning Python Part IV 之 属性继承搜索(Attribute Inheritance Search)

比起在例如C++、JAVA中,OOP在Python中理解和使用起来更简单。作为一个动态类型编程语言,Python移除了很多的复杂和混乱语法,包括其他工具中的Clouds OOP。事实上,Python中的大部分OOP赘述都可以归结为这个表达式:

object.attribute
           

之前我们已经用过这个表达式访问模块的属性、调用对象的方法等,对于一个由class语句产生的对象来说这个表达式在Python内是以搜索开始的——它搜索一个对象的相关树,寻找属性首次出现的地方,到类加入进来之后,之后的处理就可以用以下自然语言表述:

首先在object内寻找第一个出现的attribute,然后在这个类之上的所有类中寻找,按照从底向上从左到右的顺序。
           

换句话说,取属性就是树搜索。术语inheritance也适用,因为树中低级的对象从更高级的对象继承属性。随着从底向上的不断推进,在某种意义上来说,树中的对象是所有在它父对象中定义的属性的联合体。

在Python中,我们在写代码的时候建立相关的对象树,每次我们使用

object.attribute

表达式的时候,在运行时的确是从下到上的沿着树搜索属性。

Learning Python Part IV 之 属性继承搜索(Attribute Inheritance Search)

类和实例

在这个表中,有一个包含五个带有变量标注的对象。所有对象都带有属性,等待被搜索。更精确的讲,这个树是一个三个类对象(C1,C2,C3)加两个实例对象的继承搜索树。不过注意Python中的对象模型,类和由类产生的实例是两个完全不同的对象类型:

  • 类:
    扮演一个实例工厂的角色,他们的属性提供行为——数据和函数——这会被所有他们产生的实例所继承。
               
  • 实例:
    在程序域内代表具体的items。他们的属性记录数据,并且这些数据随着不同的特定对象而不同。
               

依据搜索树,一个实例从它的类继承属性,而类从树中在它之上的所有类中继承属性。

树中类的细分

在表中,我们可以根据在树中的相对位置的不同更加细化的分类。我们通常把在树中位置高一点的类称作(C2,C3)

superclasses

;位置低一点的类称作

subclasses

。这些术语涉及到了在树中的相对位置和角色。

superclasses

提供被所有

subclasses

共享的行为(behavior),但是因为搜索是从底向上推进的,

subclasses

可能会覆盖在

superclasses

中定义的行为。

继承搜索举例

因为上面的话在OOP中软件定制化中是关键,让我们扩展一下这个概念。设想我们建立一个表中的树,然后:

这个代码会引起继承,因为这是一个

object.attribute

表达式,它开始了表中树的搜索——Python会在

I2

和之上的类中搜索属性

w

。确切的讲,他会以下面的顺序搜索相关的对象:

I2,C1,C2,C3
           

然后会在第一个找到

w

的地方停下(或者没找到的话抛出错误)。在这个例子中,直到搜索到

C3

时才会找到

w

,因为只有

C3

中才有

w

,用OOP术语讲,

I2

C3

继承属性

w

这两个实例从他们的类中继承了4个属性:w,x,y和z。其他的属性引用在树中会沿着不同的路径寻找,例如:

  • I1.x 和 I2x都是在C1中找到x并停止应为C1比C2 更低
  • I1.y和I2.y都在C1中找到y因为只有C1有y
  • I1.z和I2.z都在C2中找到z因为C2比C3更靠左
  • I2.name 直接在I2中找到name,完全不需要网上寻找

仔细品味上面的例子会理解在Python中继承搜索是如何运作的。

重定义

值得注意的是,C1在树中更低级的地方重定义了属性x,取代了C2之上的版本。这样的重定义正是OOP中软件定制化的核心——重定义取代属性,C1很巧妙的定制化了从superclasses继承的东西。