title: 简明Python读书笔记 date: 2015-07-30 11:25:39 tags: [学习笔记]
更新记录
- 20150730 总结介绍
- 20150731 控制流
- 20150804 module
- 20150806 脚本练手
- 20150807 模块方法
- 20150810 是时候结束了
介绍
简记
- 这里使用的是CentOS release 6.6 (Final)
|
|
|
|
控制流
简介
- 在python中有三种控制流语句if、for、while
if语句实例
|
|
while语句实例
|
|
for语句
|
|
break语句
- break语句是用来终止循环语句的,哪怕循环条件没有称为False或序列还没有被完全递归,也停止执行循环语句。
|
|
continue语句
- 跳过当前循环块中的剩余语句,然后进行下一轮循环。
|
|
函数
- 函数是重用的程序段。它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次 地运行这个语句块,这称为调用函数。函数通过def关键字定义。def关键字后跟一个函数的标识符名称,然后跟一对 圆括号。圆括号可以包括一些变量名,该行以冒号结尾,接下来的是一块语句,它们是函数体。
定义函数
|
|
使用函数形参
|
|
局部变量
|
|
global语句
|
|
使用默认参数值
- 默认参数值是一个参数,默认参数值应该是不可变的,只有在形参表末尾的那些参数可以有默认参数值,即 你不能在声明函数形参的时候,先声明有默认值的形参而后声明没有默认值的形参,例如:def func(a,b=5) 是有效地,但是def func(a=5, b)是无效的
|
|
关键参数
|
|
return语句
- return语句用来从一个函数返回即跳出函数。也可选函数返回一个值
|
|
文档字符串(DocStrings)
- 在函数的第一个逻辑行的字符串是这个函数的文档那个字符串
|
|
模块
模块概述
- 模块的用处在于它能为你在别的程序中重用它提供的服务和功能。Python附带的标准库就是这 样一组模块的例子。
使用sys模块
|
|
字节编译的.pyc文件
- 输入一个模块相对来说是一个比较费时的事情,所以Python做了一些技巧,以便使输入模块更 加快一些。一种方法是创建 字节编译的文件 ,这些文件以.pyc作为扩展名。字节编译的文件与 Python变换程序的中间状态有关(是否还记得Python如何工作的介绍?)。当你在下次从别的 程序输入这个模块的时候,.pyc文件是十分有用的——它会快得多,因为一部分输入模块所需 的处理已经完成了。另外,这些字节编译的文件也是与平台无关的。所以,现在你知道了那 些.pyc文件事实上是什么了。
from..import语句
- 如果你想要直接输入argv变量到你的程序中(避免在每次使用它时打sys.),那么你可以使用 from sys import argv语句。如果你想要输入所有sys模块使用的名字,那么你可以使用from sys import *语句。这对于所有模块都适用。一般说来,应该避免使用from..import而使用import语 句,因为这样可以使你的程序更加易读,也可以避免名称的冲突。
- 不建议使用,尽量使用sys.argv这样的
模块的__name__(这里左右都是两个下划线)
|
|
创造自己的module
|
|
|
|
使用dir函数
|
|
数据结构
简介
- 数据结构基本上就是它们可以处理一些数据的结构,或说,它们是用来存储一组相关数据的。 在Python中有三种内建的数据结构——列表、元组和字典。
列表
- list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目。假想你有 一个购物列表,上面记载着你要买的东西,你就容易理解列表了。只不过在你的购物表上,可 能每样东西都独自占有一行,而在Python中,你在每个项目之间用逗号分割。 列表中的项目应该包括在方括号中,这样Python就知道你是在指明一个列表。一旦你创建了一 个列表,你可以添加、删除或是搜索列表中的项目。由于你可以增加或删除项目,我们说列表 是 可变的 数据类型,即这种类型是可以被改变的。
- eggs:
|
|
对象和类简介
- 列表是使用对象和类的一个例子。当你使用变量i并给它赋值的时候,比如赋整数5,你可以认 为你创建了一个类(类型)int的对象(实例)i。事实上,你可以看一下help(int)以更好地理解 这一点。 类也有方法,即仅仅为类而定义地函数。仅仅在你有一个该类的对象的时候,你才可以使用这 些功能。例如,Python为list类提供了append方法,这个方法让你在列表尾添加一个项目。例如 mylist.append(‘an item’)列表mylist中增加那个字符串。注意,使用点号来使用对象的方法。 一个类也有域,它是仅仅为类而定义的变量。仅仅在你有一个该类的对象的时候,你才可以使 用这些变量/名称。类也通过点号使用,例如mylist.field。
元组
- 元组和列表十分类似,只不过元组和字符串一样是 不可变的 即你不能修改元组。元组通过圆 括号中用逗号分割的项目定义。元组通常用在使语句或用户定义的函数能够安全地采用一组值 的时候,即被使用的元组的值不会改变。
|
|
元组与打印语句
|
|
###字典
-
只能使用不可变的对象(比如字符串)来作为字典的键,但是你可以把不可变或可变 的对象作为字典的值。基本说来就是,你应该只使用简单的对象作为键。
-
键值对在字典中以这样的方式标记:d = {key1 : value1, key2 : value2 }。注意它们的键/值对用冒 号分割,而各个对用逗号分割,所有这些都包括在花括号中。
-
字典中的键/值对是没有顺序的。如果你想要一个特定的顺序,那么你应该在使用前自己 对它们排序。
-
字典是dict类的实例/对象。
####使用字典实例
|
|
|
|
###序列
|
|
输出:
|
|
###引用
- 当你创建一个对象并给它赋一个变量的时候,这个变量仅仅 引用 那个对象,而不是表示这个 对象本身!也就是说,变量名指向你计算机中存储那个对象的内存。这被称作名称到对象的绑 定。
|
|
Output:
|
|
##编写脚本实例 ###备份脚本 Question:
- 需要备份的文件和目录由一个列表指定。
- 备份应该保存在主备份目录中。
- 文件备份成一个zip文件。
- zip存档的名称是当前的日期和时间。
- 我们使用标准的zip命令,它通常默认地随Linux/Unix发行版提供。Windows用户可以使 用Info-Zip程序。注意你可以使用任何地存档命令,只要它有命令行界面就可以了,那 样的话我们可以从我们的脚本中传递参数给它。
####Answer_1
|
|
####Answer_2
- 注意os.sep变量的用法——这会根据你的操作系统给出目录分隔符,即在Linux、Unix下它 是'/',在Windows下它是'\',而在Mac OS下它是':'。使用os.sep而非直接使用字符,会使我们的 程序具有移植性,可以在上述这些系统下工作。
|
|
####Answer_3
|
|
##面向对象的编程
###面向对象介绍
到目前为止,在我们的程序中,我们都是根据操作数据的函数或语句块来设计程序的。这被称
为面向过程的
编程。还有一种把数据和功能结合起来,用称为对象的东西包裹起来组织程序
的方法。这种方法称为面向对象
的编程理念。在大多数时候你可以使用过程性编程,但是有
些时候当你想要编写大型程序或是寻求一个更加合适的解决方案的时候,你就得使用面向对象
的编程技术。
类和对象是面向对象编程的两个主要方面。类创建一个新类型,而对象是这个类的实例 。这类
似于你有一个int类型的变量,存储整数的变量是int类的实例(对象)。
给C/C++/Java/C#程序员的注释
注意,即便是整数也被作为对象(属于int类)。这和C++、Java(1.5版之前)把整数纯粹作为
类型是不同的。通过help(int)了解更多这个类的详情。 C#和Java 1.5程序员会熟悉这个概念,因
为它类似与 封装与解封装 的概念。
对象可以使用普通的 属于 对象的变量存储数据。属于一个对象或类的变量被称为域。对象也
可以使用 属于 类的函数来具有功能。这样的函数被称为类的方法。这些术语帮助我们把它们
与孤立的函数和变量区分开来。域和方法可以合称为类的属性。
域有两种类型——属于每个实例/类的对象或属于类本身。它们分别被称为实例变量和类变量。
类使用class关键字创建。类的域和方法被列在一个缩进块中。
###self 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是 在调用这个方法的时候你不为这个参数赋值,Python会提供这个值。这个特别的变量指对象本 身,按照惯例它的名称是self。 虽然你可以给这个参数任何名称,但是 强烈建议 你使用self这个名称——其他名称都是不赞成 你使用的。使用一个标准的名称有很多优点——你的程序读者可以迅速识别它,如果使用self 的话,还有些IDE(集成开发环境)也可以帮助你。 给C++/Java/C#程序员的注释 Python中的self等价于C++中的self指针和Java、C#中的this参考。 你一定很奇怪Python如何给self赋值以及为何你不需要给它赋值。举一个例子会使此变得清 晰。假如你有一个类称为MyClass和这个类的一个实例MyObject。当你调用这个对象的方法 MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method(MyObject, arg1, arg2)——这就是self的原理了。 这也意味着如果你有一个不需要参数的方法,你还是得给这个方法定义一个self参数。
###类 ####创建一个类
|
|
**说明:**我们使用class语句后跟类名,创建了一个新的类。这后面跟着一个缩进的语句块形成类体。在 这个例子中,我们使用了一个空白块,它由pass语句表示。 我们简单地打印了这个变量的类型。它告诉我们我们已经在__main__模块中有了一个Person类的实例。 可以注意到存储对象的计算机内存地址也打印了出来。这个地址在你的计算机上会是另外一个 值,因为Python可以在任何空位存储对象。
###对象的方法 ####使用对象的方法
|
|
###使用__init__方法
- __init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希 望的 初始化 。注意,这个名称的开始和结尾都是双下划线。
|
|
###类与对象的方法
- 事实上,类与对象的数据部分只是与类和对象的名称空间
绑定
的普通变量,即这些名称只 在这些类与对象的前提下有效。 有两种类型的域
——类的变量和对象的变量,它们根据是类还是对象拥有这个变量而区分。类的变量
由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象 对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。对象的变量
由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不 是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。通 过一个例子会使这个易于理解。
|
|
- How to work: 这是一个很长的例子,但是它有助于说明类与对象的变量的本质。这里,population属于Person 类,因此是一个类的变量。name变量属于对象(它使用self赋值)因此是对象的变量。 观察可以发现__init__方法用一个名字来初始化Person实例。在这个方法中,我们让population 增加1,这是因为我们增加了一个人。同样可以发现,self.name的值根据每个对象指定,这表 明了它作为对象的变量的本质。 记住,你只能使用self变量来参考同一个对象的变量和方法。这被称为 属性参考 。 在这个程序中,我们还看到docstring对于类和方法同样有用。我们可以在运行时使用Person. __doc__和Person.sayHi.doc__来分别访问类与方法的文档字符串。 就如同__init__方法一样,还有一个特殊的方法__del,它在对象消逝的时候被调用。对象消 逝即对象不再被使用,它所占用的内存将返回给系统作它用。在这个方法里面,我们只是简单 地把Person.population减1。 当对象不再被使用时,__del__方法运行,但是很难保证这个方法究竟在 什么时候 运行。如果 你想要指明它的运行,你就得使用del语句,就如同我们在以前的例子中使用的那样。 给C++/Java/C#程序员的注释 Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。 只有一个例外:如果你使用的数据成员名称以 双下划线前缀 比如__privatevar,Python的名称 管理体系会有效地把它作为私有变量。 这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的 名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求 的(与双下划线前缀不同)。 同样,注意__del__方法与 destructor 的概念类似。
###继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过 继承 机
制。继承完全可以理解成类之间的类型和子类型
关系。
假设你想要写一个程序来记录学校之中的教师和学生情况。他们有一些共同属性,比如姓名、
年龄和地址。他们也有专有的属性,比如教师的薪水、课程和假期,学生的成绩和学费。
你可以为教师和学生建立两个独立的类来处理它们,但是这样做的话,如果要增加一个新的共
有属性,就意味着要在这两个独立的类中都增加这个属性。这很快就会显得不实用。
一个比较好的方法是创建一个共同的类称为SchoolMember然后让教师和学生的类 继承 这个共
同的类。即它们都是这个类型(类)的子类型,然后我们再为这些子类型添加专有的属性。
使用这种方法有很多优点。如果我们增加/改变了SchoolMember中的任何功能,它会自动地反
映到子类型之中。例如,你要为教师和学生都增加一个新的身份证域,那么你只需简单地把它
加到SchoolMember类中。然而,在一个子类型之中做的改动不会影响到别的子类型。另外一个
优点是你可以把教师和学生对象都作为SchoolMember对象来使用,这在某些场合特别有用,比
如统计学校成员的人数。一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可
以被视作是父类的实例,这种现象被称为多态现象。
另外,我们会发现在 重用 父类的代码的时候,我们无需在不同的类中重复它。而如果我们使
用独立的类的话,我们就不得不这么做了。
在上述的场合中,SchoolMember类被称为 基本类 或 超类 。而Teacher和Student类被称为 导出
类 或 子类 。
|
|
- How tow work 为了使用继承,我们把基本类的名称作为一个元组跟在定义类时的类名称之后。然后,我们注 意到基本类的__init__方法专门使用self变量调用,这样我们就可以初始化对象的基本类部分。 这一点十分重要——Python不会自动调用基本类的constructor,你得亲自专门调用它。 我们还观察到我们在方法调用之前加上类名称前缀,然后把self变量及其他参数传递给它。 注意,在我们使用SchoolMember类的tell方法的时候,我们把Teacher和Student的实例仅仅作为 SchoolMember的实例。 另外,在这个例子中,我们调用了子类型的tell方法,而不是SchoolMember类的tell方法。可以 这样来理解,Python总是首先查找对应类型的方法,在这个例子中就是如此。如果它不能在导 出类中找到对应的方法,它才开始到基本类中逐个查找。基本类是在类定义的时候,在元组之 中指明的。 一个术语的注释——如果在继承元组中列了一个以上的类,那么它就被称作 多重继承 。
##输入/输出 ###文件
- 通过创建一个file类的对象来打开一个文件,分别使用file类的read、readline或write方法来 恰当地读写文件。对文件的读写能力依赖于你在打开文件时指定的模式。最后,当你完成对文 件的操作的时候,你调用close方法来告诉Python我们完成了对文件的使用。
####使用文件
|
|
###储存器
- Python提供一个标准的模块,称为pickle。使用它你可以在一个文件中储存任何Python对象,之 后你又可以把它完整无缺地取出来。这被称为 持久地 储存对象。 还有另一个模块称为cPickle,它的功能和pickle模块完全相同,只不过它是用C语言编写的,因 此要快得多(比pickle快1000倍)。你可以使用它们中的任一个,而我们在这里将使用cPickle模 块。记住,我们把这两个模块都简称为pickle模块。
|
|
- How to work 首先,请注意我们使用了import..as语法。这是一种便利方法,以便于我们可以使用更短的模块 名称。在这个例子中,它还让我们能够通过简单地改变一行就切换到另一个模块(cPickle或者 pickle)!在程序的其余部分的时候,我们简单地把这个模块称为p。 为了在文件里储存一个对象,首先以写模式打开一个file对象,然后调用储存器模块的dump函 数,把对象储存到打开的文件中。这个过程称为 储存 。 接下来,我们使用pickle模块的load函数的返回来取回对象。这个过程称为 取储存 。
##异常 ###处理异常
- 使用try..except语句来处理异常。我们把通常的语句放在try-块中,而把我们的错误处 理语句放在except-块中。
|
|
- How to work 我们把所有可能引发错误的语句放在try块中,然后在except从句/块中处理所有的错误和异常。 except从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。如果没有 给出错误或异常的名称,它会处理 所有的 错误和异常。对于每个try从句,至少都有一个相关 联的except从句。 如果某个错误或异常没有被处理,默认的Python处理器就会被调用。它会终止程序的运行,并 且打印一个消息,我们已经看到了这样的处理。 你还可以让try..catch块关联上一个else从句。当没有异常发生的时候,else从句将被执行。 我们还可以得到异常对象,从而获取更多有个这个异常的信息。
###引发异常
- 可以使用raise语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你 可以引发的错误或异常应该分别是一个Error或Exception类的直接或间接导出类。
|
|
###Try finally
- 假如你在读一个文件的时候,希望在无论异常发生与否的情况下都关闭文件,该怎么做呢?这 可以使用finally块来完成。注意,在一个try块下,你可以同时使用except从句和finally块。如果 你要同时使用它们的话,需要把一个嵌入另外一个。
|
|
- How to work 我们进行通常的读文件工作,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样 做的原因是让程序运行得慢一些(Python由于其本质通常运行得很快)。在程序运行的时候, 按Ctrl-c中断/取消程序。 我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍 然被执行,把文件关闭
##Python的标准库
- Python标准库是随Python附带安装的,它包含大量极其有用的模块。熟悉Python标准库是十分 重要的,因为如果你熟悉这些库中的模块,那么你的大多数问题都可以简单快捷地使用它们来 解决。
###sys模块
- sys模块包含系统对应的功能。
|
|
###OS模块
- 简略 ● os.name字符串指示你正在使用的平台。比如对于Windows,它是’nt',而对于Linux/Unix 用户,它是’posix'。 ● os.getcwd()函数得到当前工作目录,即当前Python脚本工作的目录路径。 ● os.getenv()和os.putenv()函数分别用来读取和设置环境变量。 ● os.listdir()返回指定目录下的所有文件和目录名。 ● os.remove()函数用来删除一个文件。 ● os.system()函数用来运行shell命令。 ● os.linesep字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n',Linux使 用'\n’而Mac使用'\r'。 ● os.path.split()函数返回一个路径的目录名和文件名。 os.path.split('/home/swaroop/byte/code/poem.txt') ('/home/swaroop/byte/code', ‘poem.txt’) ● os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录。类似地,os. path.exists()函数用来检验给出的路径是否真地存在。
##参考 ###特殊的方法
- init(self, …) 这个方法在新建对象恰好要被返回使用之前被调用
- del(self) 恰好在对象要被删除之前调用
- str(self, other) 当使用小于运算符(<)的时候调用。类似地,对于说有的运算符(+, >等等)都有特殊的方法
- getitem(self, key) 使用x[key]索引操作符的时候调用
- len(self) 对序列对象使用内建的len()函数的时候调用
###参考书籍 Python标准文档(英文) Python实用大全(英文) Python常用类库(Blog) Python类库手册(中文) Python官方文档(中文)