python面向对象的特征_03 Python 关键点讲解:面向对象的机制

本节开始讲解量化交易系统最基本的编程工具 Python 的关键知识点。我们经过调研发现,目前市面上量化交易相关的书籍、课程等教学产品多数从最基础的安装、语法、函数…开始介绍 Python 这个工具,我们认为 Python 基础知识的介绍太过千篇一律,同学们上网就能搜索到基础的知识,并没有必要在此处付费去学习。另一方面 Python 这门语言工具虽然入门简单,但是深层次的一些概念并不容易理解,这里将针对于 Python 在量化交易应用中的一些关键点进行重点剖析,使同学们对 Python 语言工具有更深层次的理解。

首先我们从全局概念上先来了解 Python 面向对象的机制。面向对象是一种建立在“对象”(object)概念上来指导软件开发的方法,认为客观世界由各种对象组成,任何事物都是对象。Python 是一门面向对象的语言,因此在 Python 中一切皆为对象。接下来我们将围绕以下这幅拓扑图来描述Python 面向对象机制。

AAffA0nNPuCLAAAAAElFTkSuQmCC

拓扑图中,从左至右,框图分别代表了元类、类/类型、实例。在面向对象体系中主要存在“类”和“实例”、“父类”和“子类”这两种关系,图中虚线描述了“类”和“实例”关系, 实线描述“父类”和“子类”关系。那么我们开始逐一来介绍图中的各个元素及彼此间的关系。

1. “类”和“实例”及“父类”和“子类”的关系

在介绍“类”和“实例”及“父类”和“子类”的关系前,我们先介绍下“类”和“抽象类”。我们知道,“类”是从一堆对象中以抽象的方式把相同的特征归类得到的,由于“类”本身也是对象,那么更进一步抽象可以得到“抽象类”,两者的区别在于前者是从现实对象抽象而来的,后者是基于类抽象而来的。这里举个形象的例子来说明下,如下图所示:

AAffA0nNPuCLAAAAAElFTkSuQmCC

比如科比和梅西这两个对象抽象得到的共同特征是人,那么人作为科比和梅西的一个“类”,同理将得到的人、猫、蛇这三个“类”更进一步抽象得到的共同特征是动物,那么动物作为人、猫、蛇这三个“类”的“抽象类”。

现在我们再回过来介绍下“类”和“实例”及“父类”和“子类”的关系。“父类”和“子类”关系指的是子类继承父类的特征,同时“子类”还可以拥有自己的特征,比如人、猫、蛇这三个“类”继承了动物这个“抽象类”的特征,同时又拥有人、猫、蛇各自的特征,此时“动物”称为“父类”或“超类(Super class)、基类(Base class)”,人、猫、蛇称为“子类”或“派生类”。“类”和“实例”关系指的是“实例”对象是“类”对象的具体实现,比如有个人叫“科比”,那么“科比”就是“人”的一个实例。

总的来看,无论是继承还是实例化,它们的前提是抽象过程,只有抽象得到“抽象类”和“类”后才能展开继承和实例化过程, 这个机制的好处是可以在不改变“类”代码的基础上改变原有的功能,实现代码的重用。需要注意的是,“抽象类”只能被继承,不能被实例化,好比我们有香蕉的类、苹果的类、桃子的类,从这些类抽取相同的特征就是水果这个“抽象类”,我们吃水果时要么是吃一个具体的香蕉,要么是吃一个具体的桃子,是无法吃到一个叫做水果的东西的。

2. “元类”和“类”以及'object'和'type'的关系

我们以拓扑图中的内置类型 list 为例,结合拓扑图和例程代码我们发现 list 的“父类”是(),对于 list 的一个实例 mylist,它的类型是 ,由于“抽象类”只能被继承,不能被实例化,所以 mylist 并不存在“父类”。同理,对于内置类型 tuple、dict 或 int 也是一样。我们看到类/类型框图中 list 与元类框图中 type 之间是以虚线箭头连接的,也就是说 list 的类型是,这又是怎么回事呢?

# 例程代码

# __class__ 查看 list 的类型

print list.__class__ # 结果:

# __bases__ 查看 list 的父类

print list.__bases__ # 结果:(,)

mylist = [1,2,3]

# __class__ 查看 mylist 的类型

print mylist.__class__ # 结果:

# __bases__ 查看 mylist 的父类

print mylist.__bases__ # 结果:AttributeError: 'list' object has no attribute '__bases__'

既然说到这个地方了,我们需要介绍下元类(metaclass)。尽管 Tim Peters 说 99% 的程序猿都不需要用到元类,但是这里我们还是要对它有一个大致的了解,知道它的机制和作用,从而对 Python 面向对象有一个更全面的理解。

对象都是“类”实例化的结果,其实“类”也是对象,那它是谁实例化的结果呢?顾名思义 metaclass 就是创建“类”的模板,也就是创建“类”对象的“类”,我们称它为元类,当我们需要创造一个全新的类时可以使用元类来实现。总的关系可以归纳为,metaclass 实例化产生 class,class 实例化的结果是 instance。如下图所示:

AAffA0nNPuCLAAAAAElFTkSuQmCC

另一个问题,元类也是对象,那它是由谁实例化得到的?此处重点观察下类/类型框图中 与元类框图中 之间的关系。在拓扑图中我们看到, 和 之间同时有虚线和实线连接,object 是 type 的实例(用虚线连接),type 本身也是自己的实例(用虚线连接),同时 object 自己已经是所有类的父类(用实线连接),包括也是 type 的父类(用实线连接),因此 object 并没有“父类”。总而言之,object 和 type 是 Python 中的两个源对象,它们互相依赖对方来定义。所以在 Python 中这个追溯终止在 type 类,即元类是 type 类或其子类,而 type 类的元类就是它自己,否则会像鸡生蛋、蛋生鸡的问题那样一直下去就没有尽头了。

#例程代码

# object 是 type 的实例 .type() 方法可获取对象的类型。

print type(object) # 结果:

print object.__class__ # 结果:

# object 并没有父类

print object.__bases__ # 结果:()

# type 本身也是自己的实例

print type.__class__ # 结果:

# object是type的父类

print type.__bases__ # 结果:(,)

这里有两个面向对象的推论规则需要注意下。由于 object 是 type 的实例,同时 list、tuple、dict 是 object 的子类,那么 list、tuple、dict 也是type 的实例。另外 mylist 是 list 的实例,同时 list 又是 object 的子类,那么 mylist 也是 object 的实例。

3. 经典类(classic classes)和新式类(new-style classes)的区别

在拓扑图中除了 Python 内置类型外,我们可以通过 class 语句继承一个已存在的类/类型而创建一个新的类/类型,比如 class C(object) 继承了“父类” ‘object’ 的特征。这里有必要说下 Python 经典类 classic classes和新式类 new-style classes 的区别,classic classes 的元类是types.ClassType,而 new-style classes 的元类是 type,也就是说所有的新式类都是由 type 类实例化创建而来。在 Python 2.x 及以前的版本中我们由 class 语句创建的类对象是经典类,内置类型属于新式类,所以我们并不将类和类型混为一体。目前官方文档已经公布了消息,如下图所示:

AAffA0nNPuCLAAAAAElFTkSuQmCC

在 Python 2.7 版本中已经集成了新式类,而经典类在 Python 3.x 中被移除,也就是说在 Python3.x 及之后的版本,类和类型已经合并为一体。

我们可以通过例程代码来验证下,比如在 Python 2.7 版本中运行以下代码可知 C 的类型为老式的 classobj,如果 C 显式继承了超类 ‘object’ 就成为了新式类,Python 3.x 的运行结果与 class C 显式继承 ‘object’ 完全相同,进一步印证在 Python 3.x 中所有的类都是新式类,即显示或隐式继承自object 类。

# 例程代码

# class C 类型为老式的 classobj

class C():pass

print(type(C)) # 结果:

# class C 显式继承 'object',成为新式类

class C(object):pass

print(type(C)) # 结果:

4. 小结

Python 作为一门高级脚本语言的确上手很快,丰富的标准库可以帮助我们完成各种工作,但是当我们需要着手搭建一个系统的时候,我们需要考虑软件的可移植性、可扩展性、可维护性等等,因此我们必须深入去研究 Python 的机制,才能更好地利用它。本节对 Python 的面向对象机制进行了深入剖析,对“元类”、“类”、“实例”、“父类”、“类型”等非常重要却又容易混淆的概念和相互的关系进行详细讲解,希望能够帮助同学们理解 Python 的面向对象机制,设计出更有层次架构的软件代码。}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值