python学习笔记之六:更加抽象
Python被称为面向对象的语言,创建自己的对象是python非常核心的概念。这里会介绍如何创建对象,以及多态,封装,方法,特性,超类以及继承的概念。
一. 对象的魔力
面向对象程序设计中的术语 对象 基本上可以看做数据以及由一系列可以存取,操作这些数据的方法所组成的集合。对象最重要的几个有点包括以下几个方面:
(1)多态:意味着可以对不同类的对象使用同样的操作,它们会像被施了魔法一样工作;
(2)封装:对外部世界隐藏对象的工作细节;
(3)继承:以普通的类为基础建立专门的类对象;
1.1 多态
多态意味着就算不知道变量所引用的对象类型是什么,还是能对它进行操作,而它也会根据对象类型的不同而表现出不同的行为。
很多函数和运算符都是多态的--而你写的大多数程序可能都是,即便你并非有意这样。只要使用多态函数和运算符,多态就“消除”了。事实上,唯一能够毁掉多态的就是使用函数显示地检查类型,比如type,isinstance以及issubclass函数等。如果可能的话,应该尽力避免使用这些毁掉多态的方式。
1.2 封装
封装是对全局作用域中其他区域隐藏多余信息的原则。多态可以让用户对于不知道是什么类的对象进行方法调用,而封装是可以不用关心对象是如何构建的而直接进行使用。
假设有个叫OpenObject的类:
>>> o = OpenObject()
>>> o.setName('sss')
>>> o.getName()
'sss'
创建了一个对象,将变量o绑定到该对象上。假设变量o将它的名字存储在全局变量globalName中:
>>> globalName
'sss'
这样意味着在使用OpenObject类的实例时,不得不关心globalName的内容,要确保不会对它进行任何更改。如果创建了多个OpenObject实例的话就会出现问题,因为变量相同,所以可能会混淆:
>>> o1 = OpenObject()
>>> o2 = OpenObject()
>>> o1.setName('aaa')
>>> o2.getName()
'aaa'
可以看到设定一个名字后,其他的名字也自动设定了。这里我们就需要把名字封装在对象内,将其作为特性存储。特性是对象内部的变量。
对象有它自己的状态,对象的状态由它的特性来描述,对象的方法可以改变它的特性。所以就像是将一大堆函数捆绑在一起,并且给予它们访问变量的权力,它们可以在函数调用之间保持保存的值。
1.3 继承
继承是另一个懒惰的行为,程序员不想把同一段代码写好几次,如果已经有了一个类,又想建立一个非常类似的类,新的类可能只是添加几个方法,这时候就可以让新的类从旧的类继承方法。
二. 类和类型
2.1 创建自己的类
__metaclass__ = type class Person:
def setName(self,name):
self.name = name def getName(self):
return self.name def greet(self):
print self.name
所谓的旧式类和新式类之间是有区别的,在新式类的语法中,需要在模块或者脚本开始的地方放置赋值语句__metaclass__ = type 。
上面的例子中,class语句会在函数定于的地方创建自己的命名空间,self就是对于对象自身的引用。没有它的话,成员方法就无法访问他们要对其特性进行操作的对象本身了。
>>> foo = Person()
>>> bar = Person()
>>> foo.setName('foos')
>>> bar.setName('bars')
>>> foo.greet()
foos
>>> bar.greet()
bars
对象的特性是可以外部访问的:
>>> foo = Person()
>>> foo.name = 'ss'
>>> foo.name
'ss'
2.2 特性,函数和方法
self参数是方法和函数的区别,方法将它们的第一个参数绑定到所属的实例上,因此调用时这个参数不必提供。
默认情况下,程序可以从外部访问一个对象的特性。有人认为这样破坏了封装的原则,为了避免对象的特性被其他人误用,应该使用私有特性,这是外部对象无法访问,但是getName和setName等访问器能够访问的特性。python并不直接支持私有化,而要靠程序员自己把握在外部进行特性修改的时机。为了让方法或者特性变为私有,只要在它的名字前面加上双下划线即可。
在类的内部定义中,以双下划线开始的名字都被“翻译”成前面加上单下划线和类名的形式。
(这里我也没大看懂。)
2.3 类的命名空间
创建一个类后,所有位于class语句中的代码都在特殊的命名空间中执行---类命名空间。这个命名空间可由类内所有成员访问。
2.4 指定超类
子类可由扩展超类的定义。将其他类名写在class语句后的圆括号内可由指定超类:
__metaclass__ = type class Filter:
def init(self):
self.blocked = [] def filter(self,sequence):
return [x for x in sequence if x not in self.blocked] class spamFilter(Filter):
def init(self):
self.blocked = ['spam']
Filter类的用处在于它可由用做其他类的基类,比如spamFilter类,可以将‘spam’过滤出去:
>>> f = spamFilter()
>>> f.init()
>>> f.filter(['spam','ss','bb','spam'])
['ss', 'bb']
2.5 调查继承
如果想要查看一个类是否是另一个的子类,可以使用内建的issubclass函数:
>>> issubclass(spamFilter,Filter)
True
>>> issubclass(Filter,spamFilter)
False
如果想知道已知类的基类(们),可以直接使用它的特殊特性__bases__:
>>> spamFilter.__bases__
(<class '__main__.Filter'>,)
>>> Filter.__bases__
(<type 'object'>,)
同样,还能使用isinstance方法检查一个对象是否是一个类的实例:
>>> s = spamFilter()
>>> isinstance(s,spamFilter)
True
>>> isinstance(s,Filter)
True
>>> isinstance(s,str)
False
如果想知道一个对象属于哪个类,可以使用__class__特性:
>>> s.__class__
<class '__main__.spamFilter'>
2.6 多个超类
__metaclass__ = type class Calculator:
def calculator(self,expression):
self.value = eval(expression) class Talker:
def talk(self):
print "hi" class TalkingCalculate(Calculate,Talker):
pass
以上这种行为叫多重继承,是个非常有用的工具,但是除非读者特别熟悉多重继承,否则应该尽力避免使用,因为有时候会出现不可预见的麻烦。
当使用多重继承时,要注意一下超类的顺序:先继承的类中的方法会重写后继承的类中的方法。
python学习笔记之六:更加抽象的更多相关文章
- 【python学习笔记】6.抽象
[python学习笔记]6.抽象 创建函数: 使用def语句定义函数,不用声明参数类型,和返回值类型 def function_name(param1, param2): 'this is docum ...
- python学习笔记(五)、抽象
不知不觉已经快毕业一年了,想想2018年过的可真舒适!!!社会就像一锅水,不同地方温度不同,2018年的我就身处温水中,没有一丝想要进取之心. 1 抽象 抽象在程序中可谓是神来之笔,辣么什么是抽象呢? ...
- python学习笔记之五:抽象
本文会介绍如何将语句组织成函数,还会详细介绍参数和作用域的概念,以及递归的概念及其在程序中的用途. 一. 创建函数 函数是可以调用,它执行某种行为并且返回一个值.用def语句即可定义一个函数:(并非所 ...
- 【python学习笔记】7.更加抽象
[python学习笔记]7.更加抽象 类的定义就是执行代码块 在内存保存一个原始实例,可以通过类名来访问 类的实例化,是创建一个原始实例的副本, 并且所有成员变量与原始实例绑定 通过修改实例变量,可以 ...
- python学习笔记4_类和更抽象
python学习笔记4_类和更抽象 一.对象 class 对象主要有三个特性,继承.封装.多态.python的核心. 1.多态.封装.继承 多态,就算不知道变量所引用的类型,还是可以操作对象,根据类型 ...
- 【Python学习笔记之二】浅谈Python的yield用法
在上篇[Python学习笔记之一]Python关键字及其总结中我提到了yield,本篇文章我将会重点说明yield的用法 在介绍yield前有必要先说明下Python中的迭代器(iterator)和生 ...
- Deep learning with Python 学习笔记(10)
生成式深度学习 机器学习模型能够对图像.音乐和故事的统计潜在空间(latent space)进行学习,然后从这个空间中采样(sample),创造出与模型在训练数据中所见到的艺术作品具有相似特征的新作品 ...
- Deep learning with Python 学习笔记(4)
本节讲卷积神经网络的可视化 三种方法 可视化卷积神经网络的中间输出(中间激活) 有助于理解卷积神经网络连续的层如何对输入进行变换,也有助于初步了解卷积神经网络每个过滤器的含义 可视化卷积神经网络的过滤 ...
- Deep learning with Python 学习笔记(3)
本节介绍基于Keras的使用预训练模型方法 想要将深度学习应用于小型图像数据集,一种常用且非常高效的方法是使用预训练网络.预训练网络(pretrained network)是一个保存好的网络,之前已在 ...
随机推荐
- 福州大学第十届校赛 & fzu 2128最长子串
思路: 对于每个子串,求出 母串中 所有该子串 的 开始和结束位置,保存在 mark数组中,求完所有子串后,对mark数组按 结束位置排序,然后 用后一个的结束位置 减去 前一个的 开始 位置 再 减 ...
- 旧版QT的名称:qt-win-commercial-4.4.3-vc60.exe
qt-win-commercial-4.4.3-vc60.exeqt-vsaddin-collection-2.1.4.exeqt-win-commercial-4.4.3-v2005.exeqt-v ...
- Lucene.Net 2.3.1开发介绍 —— 三、索引(二)
原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的 ...
- 设计模式(三)-- 适配器模式(Adapter)
适配器模式(Adapter) 考虑一个记录日志的应用,由于用户对日志记录的要求很高,使得开发人员不能简单地采用一些已有的日志工具或日志框架来满足用户的要求,而需要按照用户的要求重新开发新的日志管理系统 ...
- Swift - 给表格添加编辑功能(删除,插入)
1,下面的样例是给表格UITableView添加编辑功能: (1)给表格添加长按功能,长按后表格进入编辑状态 (2)在编辑状态下,第一个分组处于删除状态,第二个分组处于插入状态 (3)点击删除图标,删 ...
- Android监听外部存储设备的状态(SD卡、U盘等等)
近期在项目中须要对外部存储设备的状态进行监听,所以整理了此笔记,以便日后查看. 外部存储设备的状态变化时发出的广播 对照不同状态下的广播 1. 插入外部SD卡时: 2. 移除外部SD卡时: 3. 连接 ...
- opencv如何载入内存中的图像文件
其实很简单,cv::imdecode 支持 std::vector<uchar>的,只要把char* 转 std::vector<uchar>就行了.用 std::vector ...
- 不是技术牛人,如何拿到国内IT巨头的Offer(转)
不久前,byvoid面阿里星计划的面试结果截图泄漏,引起无数IT屌丝的羡慕敬仰.看看这些牛人,NOI金牌,开源社区名人,三年级开始写Basic…在跪拜之余我们不禁要想,和这些牛人比,作为绝大部分技术屌 ...
- linux串口编程总结
串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...
- 取CPU序列号,获取网卡,取硬盘系列号,获取目录下的文件,强制删除目录
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...