在读过一些专业书籍之后,不得不承认老外写的书,更引人入胜。老外有严肃的专业著作,也有非常精炼而且体系结构完善的书籍能让你最快的亲近新的知识。本文就是《Think Python-How to Think Like a Computer Scientist》的读书笔记。读者可以自行下载该书的pdf进行阅读,相信和我一样,你也会受益匪浅。
经过第一遍的粗读,我将本书19章+附录分为五个部分:
Section1:编程基础
Section2:数据与存储
Section3:面向对象与类
Section4:GUI
Section5:Experience(Debugging&Python算法分析)
Section 1:编程基础
本篇为第一部分,编程基础进行总结。通过这一部分,了解和掌握Python的语法,Python中的变量、函数、和逻辑控制语句,Python的开发规范。
1-Ch1、解释器&编译器 Python是一种解释型语言(大部分脚本语言都是解释型语言)
①编译型语言,将写好的程序一次性编译成可执行的二进制代码,在机器上可直接执行。执行速度快、效率高,依赖编译器,跨平台性差,如C++
②解释型语言,程序翻译一句,执行一句,直到程序运行结束。执行速度慢、效率低,依赖解释器、跨平台性好,如Java、Python
程序经编译器编译之后可直接执行,而解释语言在被解释之后需要一个解释环境。Java是一种特殊的语言,其也需要编译,只不过是编译成字节码,然后再由解释器去逐条解释执行(JIT)。\
2-Ch1、Debugging
Syntax Error、Runtime Error(Exception)、Semantic Error- If there is a semantic error in your program, it will run successfully, but the problem is the program you wrote is not the program you wanted to write.
3-Ch1、Experiental Debugging
One of the most important skill you will acquire is debugging. Although it can be frustrating, debugging is one of the most intellectually rich, challenging, and interesting parts of programming.
Sherlock Holmes pointed out,"When you have eliminated the impossible, whatever remains, however improbable, must be the truth."
4-Ch1、Formal and natural language
Formal language are language that are designed by people for specific applications. For example, the notation that mathematicians use is a formal language that is particularly good at denoting relationships among numbers and symbols.
Programming languages are formal languages that have been designed to express computations.
5-Ch1、在Python中如何得到帮助
①、登录Python.org网站,search里面输入要查询的比如print,第一条记录就是print的相关用法
②、在解释器里面键入help(),进入帮助模块;键入quit退出help模块
③、在解释器里直接键入help('print')
6-Ch2、在不确定值的具体类型时,编译器会告诉你。如type('My'), 也可以用isinstance('my', int)-显然返回false,第二个参数是猜想的参数。
7-Ch2、zipcode = 02492, anotherZipCode = 0x3826,以0开头的数字是八进制数(Octonary number system),以0x开头的是十六进制数(hexadecimal)
8、Ch2、运算符与运算数 + - * / '//' '**'
注意:Python中有两种除法,一种是传统的/,一种是//,这种除法叫地板除法,就是向下取整
**是幂运算
9、Ch3、模块的两种导入方式
import math
from math import */pi
后者的优点是使代码变得简洁、缺点是不同模块之间的名字,或者模块与自定义的变量名容易重名
10、Ch3、调试
在文本编辑器中编写脚本时,会遇到空格和制表符的问题。避免这些问题的最好方法是只使用空格(进行缩进)。大多数识别Python的文本编辑器都默认这么做,但有些不是。
11、Ch4、案例学习、接口设计,可跳过
①、了解重构、封装、泛化(增加一个形参)的概念
②、学有余或者在对Python已经登堂入室之后,则好好看看这张的案例TurtleWorld,看看老外是怎么玩Python的,很有意思,包括第五章的习题
12、Ch5、类型检查
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">def factorial(n):
if not isinstance(n, int): # if type(n) <> int
print 'Factorial is only defined for integers'
return None
elif n < 0:
print 'Factorial is not defined for negative integers'
return None
elif n == 0:
return 0
else:
return n * factorial(n-1)</span></span></span></span></span></span>
类型检查是需要的,提高了程序的健壮性,另外,需要学习一下异常处理。13、Ch7-迭代、小tip-print函数
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">bruce = 5
print bruce,
alax = 6
print alax
cvil = 7
print cvil</span></span></span></span></span></span>
输出的效果是:
5 6
7
原因是第一条print语句之后的‘,’禁止产生新行
Section2:数据与存储
14、Ch8-字符串
① 负索引 string[-1]产生string的最后一个字母
② 字符串切片 string[m:n]返回index为[m, n)的字符;string[m:n:i]返回index在[m, n)且间隔为i的字符,如string = 'string', string[0:1]返回's';而string[0:5:2]返回srn
③ 字符串方法,书上列的很少,还需要参考其他学习资料进行学习,参照参考文献3
string.upper(), string.find('a')
④ 文件的读取
fin = open('filename.txt')
line = fin.readline()
line = line.strip() #删除line中的空格及制表符
④ Python 字符串格式化输出 http://www.cnblogs.com/vamei/archive/2013/03/12/2954938.html
15、Ch10 - for ... in 语句
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">lista = [1,2,3,4,5]
for val in lista:
val = 2;
print lista</span></span></span></span>
上述代码无法更改lista的值,如果是只读lista中的值,这种方法很好、很安全,如果要改变lista的值,就需要索引,即val[i] = 2。
16、Ch10 - 列表方法
append-追加元素;extend - 扩展元素;sort - 排序;
知道索引删除用pop,删除并返回一个元素,如果不提供索引,则删除最后一个元素;如果知道要被删除的元素,可以使用remove,remove的返回值是None;用del和切片索引可以删除多于一个元素,如del t[1:5];
split(),将字符串切割为单词列表
join(),与split相反,将单词列表合并为字符串
17、Ch10 - 列表实参
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">def add(t):
t = t + [100]
def addV(t):
t.append(100)
def deleteHead(t):
t = t[1:]
def deleteHeadHead(t):
del t[0]
t = [1,2,3]
add(t) #未能添加成功
print t
addV(t)
print t
deleteHead(t) #未能删除成功
print t
deleteHeadHead(t)
print t</span></span></span></span>
区分修改列表和生成新列表的操作非常重要,将列表作为形参,如果在函数内对列表进行修改,那么调用者会看到变化;如果在函数内生成新的列表,那么外层调用者并不能看到变化。(用Online Python Tutor来执行这个过程会比较清楚)在列表中,大部分内置函数修改实参并且返回值为None,这和字符串方法刚好相反。
Tips:用复制,尽量避免别名。
18、Ch12 - 元组的定义
- 元组更像列表,不同的是元组是不可变的(string也不可变)
- 元组是以逗号分割值的列表,虽然非必须但是通常用括号括起来,如
- 为了用一个单独的元素生成一个元组,必须包括最后的逗号,如 t = 'a', 或者 t = { 'a', }
- 生成数组的另一种方法是用内置函数tuple,如 t = tuple()
- a, b = b, a 这样就实现了a, b值的交换,显得非常的优雅
- 元组作为返回值 如,
- 汇集 *args 变长实参
- 字典有一个被称作items的方法,其返回一个元组的列表
- zip和dict的组合产生一个简洁的生成字典的方法:
- 字典方法Update也接受一个元组的列表,并作为键-值对把他们加入一个已有的字典
- 使用元组作为字典的键非常的普遍,如directory[last, first] = number
- Decorate 装饰,通过用一个或者更多排序键跟着来自序列的元素来构建一个元组列表
- Sort 排序
- Undecorate 反装饰 通过抽取排序好的序列的元素
- 字典和列表类似,但是更一般。在列表中,索引必须是整数,在字典中,它们可以是任意类型
- 创建字典:①、直接赋值;②、用内建函数,eng2sp = dict();
- in 操作符
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">eng2sp = dict()
eng2sp['one'] = 2
print eng2sp
print 'one' in eng2sp
print 2 in eng2sp
print 2 in eng2sp.values()</span></span></span></span>
打印结果分别是True False True,第一条输出语句是查找是否有键值为one,最后一条是查找是否有值为2,注意区别。
- 逆向搜索
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">def reverseLookup(d, v):
for k in d:
if d[k] == v:
return k
raise ValueError</span></span></span>
当然,上面这个只返回第一个值为v的键,如果要返回所有值为v的键,则要返回一个列表,另外,将字典的键值和值调换,用以下代码:
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">def invertDict(d):
inverse = dict()
for key in d:
val = d[key]
if val not int inverse:
inverse[val] = [key]
else:
inverse[val].append(key)
return inverse</span></span></span>
- 字典的键值必须是可哈希的
- ramdom()返回一个[0.0, 1.0)之间的浮点数
- randint(low, high)返回[low, high]之间的整数
- 为了从一个序列中随机的选择一个元素,你可以使用choice
<span style="font-size:18px;"><span style="font-size:18px;">word = 'love'
t = []
s = []
t.extend([word]*2)
s.extend(word*2)
print t
print s
print word*2
print [word]*2</span></span>
输出结果为:
['l', 'o', 'v', 'e', 'l', 'o', 'v', 'e']
lovelove
['love', 'love']
这里主要是理解extend函数的功能。区别于append。见附录5
- 打开文件 fout = open(filename, model)model可以定义为读r、写w等
- 读
- 写 fout.write(str(val))
- 格式化操作符 按照格式化操作符定义的方式来输出字符串
- 文件名与路径 import os
<span style="font-size:18px;">import os
def walk(dirname):
for name in os.listdir(dirname):
path = os.path.join(dirname, name)
if os.path.isfile(path):
print path
else:
walk(path)</span>
Section3:面向对象与类
28、Ch15 - Python类及其定义
见http://blog.csdn.net/alywinxee/article/details/46005315
29、Ch15 - 深拷贝与浅拷贝
- 别名会造成程序的可读性降低,因为一个地方的变动可能会意外影响另一个地方。跟踪所有引用同一个对象的变量是非常困难的
- 通常,用复制对象的方法取代为对象取别名
- import copy
- Example 1
<span style="font-size:18px;">p1 = Point()
p1.x = 3.0
p1.y = 4.0
p2 = copy.copy(p1)
print p1 is p2 #False
print p1 == p2 #False,与预想的有出入
</span>
==的默认行为和is相同,都是先检查身份是否一致,而非值是否一样
- Example 2
<span style="font-size:18px;">box2 = copy.copy(box)
print box2 is box #False
print box2.corner == box.corner #True
</span>
这里是浅拷贝(Shallow Copy),因为仅复制了对象以及其包含的引用,但未复制嵌套的对象
- 深拷贝(DeepCopy)
- __init__() 初始化方法
- __cmp__() 比较大小
- __str__() 用于返回一个对象的字符串表达式
- __add__() 运算符重载,该函数重载了+法
- 类型分发 P229
- __radd__() P229 右手加法 当一个Time对象在+运算符的右手边出现时调用这个方法
Section4:GUI
32、Ch19 - Thinter案例学习
- Python提供了写图形界面的几种选择:包括wxPython, Tkinter和Qt。要学会用Qt Designer进行界面设计
- An Introduction to Tkinter:http://effbot.org/tkinterbook/tkinter-index.htm
-
2014
年辛星
tkinter
教程第二版
2014
年辛星
tkinter
教程第二版
2014年辛星tkinter教程第二版:http://wenku.baidu.com/view/ae1a1957a6c30c2259019e5b.html
Section5:Experience(Debugging&Python算法分析)
附录:
1、关键字
global、
2、is 和 ==的区别
在Python中,有Frames和Objects类型的变量(参见http://www.pythontutor.com/),基础数据类型(包括字符串)属于Frames类型,而列表、元组、字典等属于Objects类型的变量。
对于Frames类型的变量,只要值相等,那么a is b 也为True
对于Objects类型的变量,即使值相等,a is b 的返回值也是False
Python中的对象包含三要素:id、type、value
其中id用来唯一标识一个对象,type标识对象的类型,value是对象的值
is判断的是a对象是否就是b对象,是通过id来判断的
==判断的是a对象的值是否和b对象的值相等,是通过value来判断的
然而,如果在别名的情况下,如:
a = 1 b = a b = 2 则结果是a = 1, b = 2
c = [1,2,3] d = c d[0] = 0 则结果是 c = d = [0,2,3],同时c is d 返回True
3、copy与deepcopy
参考文献:
1、Python变量名检测:http://ideasforjava.iteye.com/blog/649768
2、Python中的除法:http://blog.csdn.net/sicofield/article/details/8613877
3、Python中String模块:https://docs.python.org/2/library/string.html#string.Formatter
4、Python中String模块的学习:http://www.cnblogs.com/rollenholt/archive/2011/11/25/2263722.html
5、Extend(扩展)与Append(追加)的区别:http://justjavac.iteye.com/blog/1827915