读《像计算机科学家一样思考python》——笔记
这本书,完全是入门级的,特别简单,一天多就看完。
目录:
第二章 变量、表达式和语句
第三章: 函数调用
第四章: 案例研究:接口设计
第五章 条件与递归
第六章:有返回值的函数
第七章 迭代
第八章 字符串序列
第十章: 列表
第十一章: 字典
第十二章 元组
第十四章 文件
第十五章 类和对象
第十六章 类和函数
第十七章 类和方法
第18章 继承
第二章 变量、表达式和语句
1. 变量的基本数据类型:python中有 整型、长整型、浮点型、字符串型、复数形式5种。
2. 使用type( ),可以查看数据类型;如:type(2), type(‘xiaoming’) 等; type是一个函数;
3. 数值操作符:
1) 加、减、乘、除、求模和乘方: + 、-、 *、/、% 和 **
2)在python2中, 除法 / 使用的是舍去式除法(整数相除为整数), 即 2/3 结果为0; 在python3中,除数结果为浮点数类型,即 2/3 =0.6666666666666……, 并且使用一个新的操作符 // 表示舍去式除法 .
3)操作顺序: 乘方>乘除>加减
4. 字符串可以使用的操作:
1) 拼接: 使用 + , 如: ‘adfsa’+’adfds’ = ‘adfsaadfds’
2) 重复操作: 使用 * , 如: ‘abc’*3 = ‘abcabcabc’
5. 注释与换行:
# 我现在就是注释状态 print 'a' #换行使用 \ 符号; print 'asdfggk\ sdsfsf'
第三章: 函数调用
1. python中内置的类型转换函数
int 把浮点数转换为整数,它直接把小数部分舍去; 如 int(3.999) = 3; 又或 int(‘2’) = 2,它转换了字符串;
float函数将整数和字符串转换为浮点数: float(32)=32.0 或 float(‘3.14159’) = 3.14159
str函数将参数转换为字符串;
2, 定义无返回值的函数,定义方法如下, def + 函数名+() + :, 函数体要有缩进:
def hello(): print 'hello,world!' print 'hello, yinheyi'
3. python提供了两种导入模块的方式:
方法一: import 模块名, 如 import math , 这时如果访问模块里面的函数的时候,需要同时指明模块名与函数名,中间用 . 分隔;
方法二: from 模块名 imort 函数名, 这时,我们就可以直接使用这个函数名了,并且不需要指明模块名; 使用 from 模块名 import * 导入模块的所有成员;
优缺点: 第二方式可以使代码更简洁,但是,不同模块的同名成员之间,可能发生冲突;
第四章: 案例研究:接口设计
1. 一个开发计划:
1) 最开始写一些小程序, 而不需要函数定义;
2) 一旦程序成功运行,将它封装到一个函数中,并加以命名;
3) 泛化这个函数,添加合适的形参;
4) 可以使用重构来改善程序的机会, 例如, 如果发现程序中几处地方有相似的代码,可以老柴将它们抽取出来做一个合适的通用函数。
2. 文档字符串:
它的作用:在函数开头用来解释其的字符串。
def hello(): """ 这是一个文档字符串, 使用三个引号 可以允许字符串跨行表示; 我现在就跨行了啊; """ print "hello,world!"
注意:编写这类文档是接口设计的重要部分. 一个设计良好的接口, 也应当很简单就能解释清楚;
第五章 条件与递归
1. 关系操作符:
不等于 | != |
大于 | > |
小于 | < |
大于等于 | >= |
小于等于 | <= |
2. 逻辑操作符:
与 | and |
或 | or |
非 | not |
3. 布尔值与布尔表达式:
表达式的值是真或假的表达式,就是布尔表达式。 它的值为 True或False, 它们并不是字符串。
4. 空语句: 在python中, 空语句使用 pass,记好!!!!
5. 条件判断表达式:
1) 只有一个分支:
if x < y: print 'x is less than y'2)有两个分支:
if x < y: print 'x is less than y' else: print 'x is large than y'3) 多个分支:
if x < y: print 'x is less than y' elif: print 'x is large than y' else: print 'x is equal to y'
6. 从键盘输入:
python 2 提供了内置函数 raw_input 来从键盘获取输入, python 3 中这个函数改为了 input, 不过它们的用法相同。
a = raw_input('input your name:\n') print 'hello '+a+'!'
#输出为: input your name: yinheyi hello yinheyi!
第六章:有返回值的函数
1. 增量开发程序:
这个思想真的很好, 我们可以把一个大的函数一点点的增加开发出来 ,慢慢的一点点的调试。增加一些必要的脚手架代码。 比如,在关键的位置打印一下变量的值等。一步步地来,保证每一步都是正确的, 这样可以幚我们节省大量的调试时间。
2. 有返回值的函数: 返回值使用 return 返回。
def sum(a, b): temp = a + b return temp
3. 坚持信念:
在写递归函数的时候, 我们可以使用一个方法: 坚持信念。 当我们遇到一个函数的调用的时候,不去跟踪执行的流程,而是我们假定函数是正确工作的,能够返回正确的结果 。如著名的斐波那契数列,它的程序可以写作:
def fibonacci(n): if n == 0: return 0 elif n == 1: return 1 else: return fibonacci(n-1) + fibonacci(n-2)
4. 检查类型:
python中内置了一个函数 isinstance 来检查的实参的类型, 正确返回True, 否则返回 False
isinstance(12, int) True >>> isinstance(12.2, float) True >>> isinstance('hello', str) True
第七章 迭代
1. while 循环:
while n < 100: print n n = n - 1
2. for 循环:
for i in range(100): print i i = i + 1
第八章 字符串序列
1. 字符串是一个序列,它的下标是0 开始的; 使用python的内建函数len() 可以返回字符串中的字符的个数:
>>> a = 'hello' >>> len(a) 5 >>> a[0] 'h'
可以使用for 循环来遍历一个字符串内的字符:
a = 'hello' for char in a: print char
2. 对字符串可以切片:
操作符[n:m] 返回字符从第n个字符到第m个字符的部分, 包含第n 个字符,但是不包括第m个字符。
>>> fruit = 'banana' >>> fruit[1:3] 'an' >>> fruit[:2] 'ba' >>> fruit[3:] 'ana'
3. 操作符 in
in 是一个布尔操作符, 操作于两个字符串上,如果第一个是第二个的子串,则返回True, 否则返回 False。
>>> 'yin' in 'yinheyi' True
4. 字符串中的元素是不可以改变的;
第十章: 列表
1. 列表是一个序列, 在列表中,它的值可以是任何类型, 列表中值称为元素;列表可以嵌套在一个列表中。
创建一个列表最简单的方法使用[ ], 如: [10, 20, 40, ‘xiaoming’]
2. 使用 [] 操作符来访问列表, 列表中的元素是可以变化的;
3. 遍历一个列表,照样可以使用for()循环;
for i in array: print i
4. 列表操作:
1) + 操作,可以用于拼接列表;
2) * 操作符,可以用于重复一个列表多次;
5. 从列表中删除元素:
1)使用下标删除: pop 修改列表,返回被删除的值,如果不提供下标,它会删除并返回最后一个元素;
t = ['a', 'b', 'c'] print t.pop(1) #输出:b print t #输出:['a', 'c']2) 使用下标删除, 不返回删除的值,使用del操作符:
>>> t =[1, 2, 3, 4] >>> del t[1] >>> print t [1, 3, 4] >>> t =[1, 2, 3, 4] >>> del t[1:3] >>> print t [1, 4]3)如果知道删除的元素,则可以使用remove:
>>> t = ['a', 'b', 'c', 'd', 'e'] >>> t.remove('d') >>> print t ['a', 'b', 'c', 'e']
6. 把字符串转化为列表:
1)转换为单个单词: 使用函数:list
2)转换为一个个的单词, 使用字符串的方法 split()>>> t = 'asdfas' >>> print list(t) ['a', 's', 'd', 'f', 'a', 's']>>> t = 'hello world yinheyi' >>> print t.split() ['hello', 'world', 'yinheyi']
7. 一个有趣的例子:
>>> a = 'aaa' >>> b = 'aaa' >>> a is b True >>> a = ['a', 'b', 'c'] >>> b = ['a', 'b', 'c'] >>> a is b False
为什么会这样子? 也没有什么意思吧。。字符串是同一个对像, 而列表不是同一个对象,其实也很容易理解, 字符串不可以更改,而列表是可以更改的;
8. 很重要:别名
当我们使用赋值 b =a 时, 这两个变量都会引用同一个对象,改变其中一个,必然会影响另一个,这个与C语言不同,因为C语言中,它们是两个不同的对象;例子如下:
>>> a = [111, 222, 333] >>> b = a >>> b[0] = 444 >>> print a [444, 222, 333]
9. 列表参数:
当我们将一个列表作为参数传入到函数中时, 函数会得到列表的一个引用。 所以,在函数中修改了列表的话,对函数外也有影响;
这一章特别注意: 对于列表进行赋值,是得到了原来列表的一个引用, 是引用啊。要特别曲分修改列表还是新建了一个列表;
第十一章: 字典
1. 字典是一个键值对的组合,
新建方法:使用内置函数 dict 新建一个不包含任何项的字典。添加元素的话,就可以如此操作:
>>> a = dict() >>> a['first'] = 'yinheyi' >>> print a {'first': 'yinheyi'}
记住:字典中的各项顺序是不可预料的,即不是确定的,因为本来就与顺序无关,它使用键来查找对应的值。
函数 len : 它返回一个字典的键值对的数量;
函数 in : 它可以告诉一个指定的值是不是字典里面的键。
注意: in 操作符对于列表和字典使用不同的算法实现, 对于列表, 它使用搜索算法, 当列表变长时,搜索时间会随之变长。 对于字典,python使用一个称为 散列表 的算法, 不管字典中有多少项,in 操作符花费的时间都差不多。
2. 循环与字典:
如果在 for 循环中使用字典, 会遍历字典的键。
3. 使用字典的备忘 来解决fibonacci 问题,真的可以提高效率啊:
21 def fibonacci(n): 22 if n in known: 23 return known[n] 24 25 res = fibonacci(n-1) + fibonacci(n-2) 26 known[n] = res 27 return res
第十二章 元组
1. 元组是一个序列, 它与列表很相似,也按照整数下标索引. 它们之间的重要区别就是: 元组是不可变的;
新建一个元组的方法: 注意使用括号哦;
a = ('a', 'd', 'e')
也可以使用内建的函数 tuple 新建一个空元组:
t = tuple()
2. 作为返回值的元组:
在python中 ,函数只能返回一个值, 如何让函数返回多个值呢?我们可以把一个元组当作函数的返回值,这样的话,相当于函数返回多个值了;
def sb(): 2 a = 1 3 b = 2 4 return a, b 5 6 num = sb() 7 print type(num) #输出:<type 'tuple'>
3.
第十四章 文件
1. 读和写
一个文件需要先打开,然后再进行读与写, 最后把打开的文件关闭。
#读文件 >>> f = open('words.txt') >>> print f <open file 'words.txt', mode 'r' at 0x7fd74378e4b0> >>> f.readline() 'aa\r\n' >>> f.close() # 写文件 >>> f = open('sb.txt', 'w') >>> print f <open file 'sb.txt', mode 'w' at 0x7fd74378e540> >>> line = "hello, world!\n" >>> f.write(line) >>> f.close() >>> exit()
注意:要写入一个文件,需要使用 ‘w’模式作为第二个实参开打开它。如果文件已经存在,则使用写模式打开时会清除掉旧的数据并重新形如,所以特别注意啊。如果文件不存在,则新建一个。另外, write的参数是必须是字符串。
2,格式操作符
它与c语言中printf()里面的格式化字符串类似的,可以格式化输出。 %d 用于格式化整数, %g 用于格式化小数,%s 用于格式化字符串。
当字符串中有一个格式序列时,
>>> print 'I have %d pens' % 12 I have 12 pens
当字符串中有多个字符序列时, 第十个操作对象就必须是元组。 并且每个格式序列按对应元组中的一个元素。
>>> print 'In %d years I have spotted %g %s.' % (3, 0.1, 'camels') In 3 years I have spotted 0.1 camels.
3. 文件名与路径
os模块提供了用于操作文件和目录的函数, 具体可以查看一下这个模块的相关函数。
4. 捕获异常
可以使用 try语句来捕获一个异常,例子如下:
try: fin = open('1123.d') print '打开成功' fin.close() except: print '没有打开成功,可能文件不存在\n'
5. 数据库: 模块anydbm 提供了接口用于创建和更新数据库的文件。 anydbm模块的限制之一是键和值都是字符串,即它只能保存字符串。 pickle模块可以把几乎所有类型的对象转换为适合保存到数据库的字符串形式, 并可以将字符串转换成为对象。 python将上面这两个模块封装起来成为了一个模块,叫做 shelve.
6. 管道 ( os.popen()现在已经废止了,但是还没有完全废止)
任何在字符界面能启动的程序都可以在python 中通过一个管道来启动。 它的返回值和一个打开的文件差不多。
>>> cmd = 'ls -l' >>> fp = os.popen(cmd) >>> print fp.read() 总用量 1156 drwxrwxr-x 3 yinheyi yinheyi 4096 Sep 20 17:34 2048 -rwxrwxr-x 1 yinheyi yinheyi 8519 Oct 27 20:29 a.out -rw-rw-r-- 1 yinheyi yinheyi 95 Oct 27 20:29 hello.c -rw-rw-r-- 1 yinheyi yinheyi 75 Oct 31 14:26 hello.py -rw-rw-r-- 1 yinheyi yinheyi 140 Oct 31 22:10 main.c -rw-rw-r-- 1 yinheyi yinheyi 218 Oct 31 22:11 Makefile -rw-rw-r-- 1 yinheyi yinheyi 14 Nov 1 09:52 sb.txt -rw-rw-r-- 1 yinheyi yinheyi 214 Nov 1 10:17 sum.py drwxrwxr-x 4 yinheyi yinheyi 4096 Sep 20 17:18 Tinyhttpd -rw-rw-r-- 1 yinheyi yinheyi 423 Oct 31 20:13 turtle.py -rw-rw-r-- 1 yinheyi yinheyi 1130523 Oct 31 16:43 words.txt >>> print fp.close()
7. 编写模块:
我们可以把任何包含 pyhon 的代码的文件都可以作为模块导入。 里面定义了函数的话, 我们就可以调用它。
说明一点:为了模块内的部分没有必要的代码被执行, 通常把这部分代码写入到如下模式中去:
if __name__ == '__main__': print 'hello, world!' ……
__name__ 是一个内置变量,当程序启动时就会被设置, 程序作为脚本执行, __name__ 的值就是 __main__ ,此时, 下面代码会被执行。当作为模块被导入时, 这部分代码就会被跳过。
第十五章 类和对象
这本书上,这一节讲的实在太简单表面了,,没有什么可以作为笔记的;
第十六章 类和函数
1. 什么是纯函数?一个函数它坠子返回一个值之外, 并不修改作为实参传入的任何对象, 也没有任何如显示值或获得用户输入之类的副作用。
2. 什么是修改器? 有时候用函数修改传入的参数对象是很有用的。在这种情况下, 修改对调用者是可见的, 这样工作的函数称为修改器。
第十七章 类和方法
1. 对于写在类内部的函数,我们把它称为方法。
当我们调用一个方法时,直接使用主体与方法名称就可以了,比如(xiaoming 是一个主体,而h1为一个方法名称):
class hello(object): def h1(): print 'hello, world!' xiaoming = hello() xiaoming.h1()
在方法中, 主体会被赋值到第一个形参上。 依惯来, 方法的互一个形参通常叫做 self。
2. 类的 init 方法
init 方法是一个特殊的方法,当对象初始化时会被调用。它的全名是 __init__。比如:
def __init__(self, hour = 0, minute = 0, second = 0): self.hour = hour self.minute = minute self.second = second
2. 类的 __str__方法
__init__也是一个特殊方法, 它用来返回对象的字符串的表达形式。当我们打印对象的结果时, python 会调用__str__方法。定义例如:
def __str__(self): return '%d %d %d' % (self.hour, self.minute, self.second)
3. 操作符重载
通过定义其它特殊方法, 我们可以为用户定义类型的各种操作符指定的行为, 比如:当我们定义一个名为 __add__ 方法时, 则可以在时间对象上使用 + 操作符。 其它的操作符都有相应的特殊名字的方法。
4. 多态问题
书中没有详细说明,等着再参考其它的学习资料吧。