黑体表示章节, 下划线表示可以直接在原文对应位置查到的专有技术名词。
原书配套答案请到http://www.hzbook.com/Books/4572.html下载,简单注册即可。
第三章 如何运行程序
import进行模块导入只能运行一次,多次运行需使用reload。
模块往往是变量名的封装,被认为是命名空间。例如:
#myfile.py title = "test" >>>import myfile >>>print myfile.title test
替代方案是from,下面有同样的效果:
>>>from myfile import title >>>print tittle test
from myfile import * 则可以把myfile所有变量全部导入(第19章内容)。
第四章 介绍Python对象类型
虽然字符串支持多种操作,但是它具有不可变性,即原字符串不能改变,只能用新字符串作为结果赋予一个变量。下面是一个试图改变原字符串的操作及报错信息:
>>> s="spam" >>> s[0] = 'z' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment
第五章 数字
str和repr显示格式
>>>num = 1/3.0 >>>num 0.33333333333333331 >>>print num 333333333333 >>>repr(num) '0.33333333333333331' #交互模式回显 >>>str(num) '333333333333' #打印语句
浮点数运算在精确方面有缺陷。这和硬件有关,打印结果也不能完全解决。
>>> 0.1+0.1+0.1-0.3
5.551115123125783e-17
>>> print 0.1+0.1+0.1-0.3
5.55111512313e-17
使用小数对象可以进行修正
>>> from decimal import Decimal >>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3') Decimal('0.0')
第六章 动态类型简介
a = 3这个语句实际上执行了三个步骤:创建一个对象代表值3;如果还未创建,创建一个变量a;将变量与新的对象3连接。这时,变量a成为了对象3的一个引用,也可以看做是指针。
类型属于对象,而不是变量,这就很好理解为什么Python中同一个变量名可以作为不同类型的对象的引用了。
在这种机制下,每个对象都有一个引用计数器,当计数器为0时就被系统回收,这便是Python中对象的垃圾收集的方法了。
不同变量引用同一个数字或字符串时,对变量操作(eg.a=3 a=a+2)只是创建了一个新的对象并使它引用新对象,这也是上一章提到的字符串不能改动的原因。而对于一些类型来说,有的操作确实能改变对象,如下所示:
#situation 1 >>>L1=[2,3,4] >>>L2=L1 >>>L1=24 >>>L2 [2,3,4] #situation 2 >>L1=[2,3,4] >>>L2=L1 >>>L2[0]=24 >>>L1 [24,3,4]
为了让两个变量使用不同的对象,可以拷贝对象,使用L2=L1[:]来代替L2=L1即可。对于字典则使用D.copy()方法。标准库的copy模块提供了一个对任意对象的调用方法,下面两种方式的区别暂不讨论:
import copy X = copy.copy(Y) #表层拷贝 X = copy.deepcopy(Y) #深拷贝
这里就出现了个问题,两个引用是否是同一对象?可以用下面的方式判断:
>>>L=[1,2,3] >>>M=L >>>L== M True >>>L is M True
负值索引相当于从末尾倒数。-1就是最后一个元素的索引。对于s="spam",-5是个非法的索引值。分号:前的空值表示从第一个开始,后的空值表示直到最后一个。
第七章 字符串
单双引号是一样的,这样允许用户不使用转移字符来实现带有单或双引号的字符串。个人认为避免了按shift才能使用双引号“的麻烦。
>>>'knight"s ',"knight's" ('knight"s ',"knight's")
此外,合并相邻的字符串常量,如'knight"s ' "knight's"(中间有空格)会显示为'knight"s knight\'s'。可见,最外层是单引号,为了保持原内容,Python把单引号里的单引号改写成了转义字符,这个例子和书上的不同,更有助于理解。转义字符和C很类似,多了几种;但是Python里没有空字符串,Python为每个字符串保存了内容和长度。同时,如果一个字符串中没有合法的转义编码出现在"\"后,那么它将在字符串中保留反斜线。抑制转义的方法是在字符串前加r,如r"C:\new\text.dat",此时的\n和\t就不会被当做是转义字符,同时,这样做也不必把\改写成\\。
三重引号适用于多行的字符串的直接输入而不使用转义字符。利用三重引号也可以实现类似C中/* */注释掉代码的目的。
Unicode字符串通过在前面加u获得。
扩展分片是第三个索引,用作步进。这时完整的分片形式为X[I:J:K],其中步进为K。当步进取-1时,可以把字符串反转,很神奇的方法。
利用分片,可以对字符串进行修改,即把新字符串加到原字符串上,再把原字符串切掉。
字符串格式化的用法与C的printf很像,不同之处在于所有参数外需要加一个(),形成%(arg1,arg2,arg3)的形式。格式化代码请参考原书表格,通用结构:%[(name)][flags][width][.precision]code,其中name可以是字典名,这时在参数表里提供这个字典的键即可。
既然字符串是对象,那么它就有对应的方法。书上介绍了修改字符串的replace()、查找find()、把每个元素取出创建列表的list()、把列表合并成字符串的join()(可以作为list()的反操作)、提取组件的split()。
第八章 列表
用中括号表示列表,列表的组成对象是有序的,组成列表的各个对象允许不同。
用大括号表示字典,字典的组成对象是无序的,字典键的搜索方式是哈希搜索,速度很快。
可以用字典来模拟列表:使用序数作为字典的索引即可。类似地,字典可以用来表示一些稀疏矩阵。
字典的get方法用于避免不存在的键,如果键不存在,返回值是0。
字典接口是使用方式类似字典并且实际工作都和字典一样的一些Python扩展程序的接口。
第9章 元组、文件及其他
用小括号表示元组,元组不能原处修改。
为了避免只含一个元素的元组被当做表达式,使用一个逗号,写为(40,)。逗号可以帮助识别元组,下面的也是元组的表示方式:
t = 0,'Ni',1.2,3
从文件中读取的是字符串,需要作为其他类型来操作时必须转换。
eval()用来把字符串作为对象,因此也可以达到执行Python的任何表达式。
pickle模块可以直接在文件中存储几乎任何Python对象。
struct模块提供了二进制数据的打包。打包+存入文件,读取文件+解包。
在“赋值VS引用”这一节,对于复合方式的赋值,修改其成员会导致所有使用该成员的对象的改变。直观来看就是下面:
>>>X = [1,2,3] >>>L = ['a', X, 'b'] >>>D = {'x':X, 'y':2} >>>X[1] = 'surprise' >>>L ['a', [1,'surprise',3], 'b'] >>>D {'x':[1,'surprise',3], 'y':2}
这是一个陷阱,为了避免这种情况,根据具体类型使用拷贝(比如分片、copy方法)而不是引用。
Python内部暂时存储并重复使用短字符串,因此对同样内容的字符串,is判定可能根据其长度为True(字符串较短时)或False(字符串较长时)。不同类型的比较(用==进行)的判定方式不一样。
还有其他内置类型陷阱,如重复能增加层次深度,循环数据结构L=L.append(L)
第二部分练习题
2.(摘自附录B)分片运算超出边界(例如,L[-1000:100])可工作,因为Python会缩放超出边界的分片(必要时,限制值可设为零和序列长度)。以翻转的方式提取序列是行不通的(较低边界值比较高边界值更大,例如,L[3:1])。你会得到空分片([ ]),因为Python会缩放分片限制值,以确定较低边界永远比较高边界小或相等(例如,L[3:1]会缩放成L[3:3],空的插入点是在偏移值3处)。Python分片一定是从左至右抽取,即使你用负号索引值也是这样(会先加上序列长度转换成正值)。注意到,Python 2.3的第三限制值分片会稍微修改此行为:L[3:1:-1]的确是从右至左抽取。
3.索引运算、分片运算以及del:对于L=[1,2,3,4], L[2] = []只能把3变为[],而L[2:3] = []却能删掉第三项。
4.X,Y = Y,X,左边视为两个对象,右边视为一个元组,这个表达式交换了两个引用。
第10章 Python语句简介
绝大多数的Python程序每行一个语句,不需要分号。Python的风格就是完全不要分号,虽然在语句末加上分号也能通过。唯一需要分号的情况是一行中多个语句的分隔符。相反地,括号可以使一个语句分隔成很多行,比如用列表直观地定义一个矩阵时。反斜线\也可以达到这个目的。
嵌套代码只需要保持缩进一致即可。Python是WYSIWYG语言(what you see is what you get,所见即所得)
第11章 赋值、表达式和打印
形如X+=Y的赋值语句称为增强赋值语句,它有三个优点:程序员输入减少,左侧只需要计算一次(X=X+Y中X计算两次),优化技术会自动选择(支持原处修改的类型可以直接原处修改)。
单一下划线开头的变量名不会被from module import *这样的语句导入。前后都有双下划线的变量名是系统定义的变量名,对解释器有特殊意义。双下划线开头但结尾没有双下划线的变量是类的本地变量(参考第19章)。
表达式语句通常用于执行可原处修改列表的列表方法,即对于列表L,L.append(3)是正确的,而L=L.append(4)是错误的,第二个式子右边返回的是None。
标准输出的重定向方法:
import sys sys.stdout = open('log.txt','a') ... print x,y,x #写入log.txt
为了避免忘记恢复sys.stdout,写入log.txt也可以用:<