python基础教程复习笔记7: 更加抽象

更加抽象

前几章节介绍了python主要的内建类型,以及内建函数和标准库的用法,还有定义函数的方法.现在看来,还差一点,创建自己的对象,这正是本章要介绍的内容.

7.1 对象的魔力

对象的定义

在面向对象程序设计中,对象,基本上可以看做数据(特性)以及一系列可以存取,操作这些对象的方法所组成的集合.

对象的优点

  • 多态(ploymorphism):意味着可以对不同的类的对象使用相同的操作
  • 封装(encapsulation):对外部世界隐藏对象的工作细节
  • 继承(inheritance):以通用的类为基础建立专门的类的对象

7.1.1 多态

多态的定义

  • 多态术语来源于希腊语,意思是有多种形式
  • 意味着就算不了解变量所引用的对象类型是什么,还是能对它进行操作,而它也会根据不同的对象(或类)类型的不同表现出不同的行为

多态和方法

  • 绑定到对象特性上的函数,叫做方法
  • 不需要检测类型,只需要知道x有个叫做xfunc的方法,接受某个参数,并有某种功能即可

多态的多种形式

  • 很多内建的运算符和函数都有多态的性质,它们的参数可以是任何支持此种运算或者操作的对象.
  • 事实上,唯一能毁掉多态的就是使用函数显示地类型检查,比如type isinstance issubclass函数等,如果可能,尽量避免使用这些毁掉多态的形式

7.1.2 封装

封装的定义

  • 封装是指向函数中其他部分隐藏对象的具体实现细节的原则
  • 多态可以让用户对于不知道是什么类的对象进行方法调用,而封装是可以不用关心对象是如何构建的而直接使用

封装的优势

  • 变量可以作为特性(attribute)储存在类/对象之中
  • 对象有自己的状态(state),由自己的特征描述
  • 对象的方法有访问特性的权利

7.1.3 继承

以通用的类为基础建立专门的类的对象

7.2 类和类型

7.2.1 类到底是什么

  • 类,可以将它多少地视为种类或者类型的同义词
  • 类也是一种对象
  • 所有的对象都属于某一个类,被称为类的实例
  • 当一个对象所属的类是另外一个对象所属类的子集时,前者就被称为后者的子类(subclass),相反,后者是前者的超类(superclass)

命名规则

日常中,可能经常用复数来描述对象的类,python中,习惯使用单数名词,并且首字母大写

注意

在旧版本python中,类和类型有明显的区别,内建的对象是基于类型的,自定义的对象是基于类的.可以创建类但不能创建类型.最近版本中,基本类型和类之间界限开始模糊,乃至python3的最新版本中,默认全部为新式类,可以创建内建类型的子类

7.2.2 创建自己的类

7.2.3 特性,函数和方法

自己参数

  • self参数实际上正是函数和方法的显式区别,方法(或称为绑定方法)将他们的第一个参数绑定到所属的实例上,在调用时,无需显式的提供这个参数
  • 当然也可以在外部定义一个函数,然后将方法绑定到其上,这样就没有特殊的self参数了
  • self参数并不依赖于调用的方法,即使你将一个名字绑定到上面,提供参数时也无需self的显式提供

再论私有化

一般来说,作为封装的辅助和保证,面向对象语言应该提供私有(private),但是python并不直接支持私有方式,要靠程序员在外部把握进行特征修改的时机

以下的一些小技巧,可能间接的达到私有的效果

前面带有下划线的语句都不会被from module import *导入

7.2.4 类的命名空间

下面两个语句(几乎)等价:

所有位于class语句都在特殊的命名空间内执行–类命名空间

这个命名空间可由类内所有成员访问

7.2.5 指定超类

形式

两个要点

  • 可以使用新定义的方式重写方法的定义
  • 可以继承一些定义避免全部重写

7.2.6 检查继承

7.2.7 多个超类

  • 一个子类可以从多个超类继承–这种行为可以称为多重继承
  • 如果一个方法从多个超类继承时,必须注意继承的顺序,先继承的方法会重写后继承的类的方法
  • 如果超类们又共享一个超类,那么在查找给定方法或属性时,访问超类的顺序称为(MRO,Method Resolution Order),使用的算法相当复杂,工作的很好,无需关心

7.2.8 接口和内省

接口

  • 接口的概念与多态有关,在处理多态对象时,只要关心他的接口(或称为协议),也就是公开的方法或特性
  • 在python中,不需要显式的编写接口,可以在使用对象时假定他可以实现你要求的行为,如果不能实现就会引起错误
  • 除了调用方法然后期待一切顺利之外,还可以检查所需方法是否已经存在.如果不存在还要做一些其他的事情

要查看对象内所有储存的值,可以使用__dict__特性,要想真正找到对象由什么组成,可以看看inspect模块

7.3 一些面向对象的思考

  • 将属于一类的对象放在一起,如果一个函数操纵全局变量,那么两者最好都在类内作为特征和方法出现
  • 不要让对象过于亲密,方法应高只关心自己的实例
  • 要小心继承,尤其是多重继承,但在某些情况下会变得复杂,它难以正确使用,也难以调试
  • 简单就好,让你的方法小巧:一般来说,多数方法都应该能在半分钟之内读完并且理解
  • 当考虑需要什么类以及应当有什么方法时,尝试以下方法
    • 写下问题的描述,把所有名词动词以及形容词加下划线
    • 对于所有的名词,用于可能的类
    • 对于所有的动词,用于可能的方法
    • 对于所有的形容词,用于可能的特性
    • 把所有的方法和特性分配到类
Tagged with:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据