《Python 基础教程》笔记
第1章
幂运算符:**,不是^
长整数:在整数结尾加上L,如:100000000000000000000L
Python 3中,print 从语句变成了函数,print 42
要写成 print (42)
在UNIX系统下,在脚本开头加上 #!/usr/bin/env python
可以让脚本像普通程序一样执行,不需要显式地使用Python解释器
Python 3.0 已不再使用反引号,应该使用 repr()
函数
input
和 raw_input
:input
需要用户输入合法的 Python 表达式。Python 3.0 中,raw_input
被重新命名为 input
。
原始字符串 r’c:\windows’
(类似 Objective-C 中的 @“"?)
原始字符串的最后一位不能是''
原始字符串在写正则表达式的时候很有用
Unicode 字符串 u’hello, world'
第2章 列表和元组
两种主要的容器:序列和映射。序列一共有六种,包括列表和元组(不可变列表),还有字符串、Unicode字符串、buffer对象、xrange对象。
注意:负数索引
通用序列操作:索引、分片(slicing)、加、乘;计算长度、最大最小值;迭代。
slicing 的应用:复制表
>>> x = [1, 2, 3]
>>> y = x[:]
检查成员资格(某元素是否在容器中):in 运算符。
list
,将字符串转换为列表
>>> list(‘hello’)
[ ‘h’, ‘e’, ‘l’, ‘l’, ‘o’ ]
分片赋值。可插入与原分片不等长的列表。可以利用分片赋值实现删除元素。
列表方法:append
, count
, extend
, index
, insert
, pop
, remove
, reverse
, sort
tuple
函数(其实不是函数,是类)可以将序列转换为元组
关于元组,这句话很精辟:
除了创建元组和访问元素之外,也没有太多其他操作。
元组的作用:元组可以在映射中当作键使用(?);很多内建函数和方法的返回值是元组。
第3章 字符串
格式化字符串时,如果字符串本身包括 ‘%',需要使用’%%'的形式。
字符串格式化(这部分写得很全面)
字符串方法:find
, join
, lower
, replace
, split
, strip
, translate
第4章 字典
字典是 Python 唯一的内建映射类型。
dict
函数,从列表或其他映射建立字典
?什么是关键字参数。例如:从关键字参数建立字典 d = dict(name='michael', age=42)
使用字典格式化字符串,%后面使用括号,表示这里是一个字典的 key
字典方法: clear
, copy
, fromkeys
, get
, has_key
, items
, iteritems
, values
, itervalues
, keys
, iterkeys
, pop
, popitem
, setdefault
, update
,
注意,popitem
实际上是 随机 弹出一个值,因为字典不保存 items 的顺序(在 JavaScript、JSON 中也是这样)。
第5章 条件、循环和其他语句
赋值语句
交换两个变量的值:x, y = y, x
。这里用到的特性叫做“序列解包(sequence unpacking)”。处理返回元组的函数,序列解包特性十分有用:key, value = dict.popitem()
。。
Python 3.0 之前,不兼容类型比较(例如比较一个整形数和一个字符串)不会导致语法错误,但是结果是不可预期的。Python 3.0 起,不再允许比较不兼容类型。
短路逻辑(惰性求值)示例:name = raw_input('input name...') or 'unknown'
只要能使用 for 循环,就不要用 while 循环。
zip()
函数可以将两个序列压缩到一起。
使用 for item in list:
处理列表时,如果需要得到 index,可以使用 enumerate()
函数:for index, item in enumerate(list):
在循环中使用 else 子句,表示循环没有被 break 语句打断而跳出。
from math import sqrt
for n in range(99, 81, -1):
root = sqrt(n)
if root == int(root)
print n
break
else:
print "didn't find it!"
列表推导:用其他列表创建新列表。可以结合条件判断语句:
[x*x for x in range(10) if x % 3 == 0]
命令空间类似于不可见的字典。
第6章 抽象
文档字符串
def square(x):
'计算x的2次方'
return x ** 2;
函数的位置参数与关键字参数。关键字参数结合默认值使用,非常方便。
收集参数(不确定参数个数),将其后的所有参数收集到一个元组中。
关键字参数需要使用 **
,将关键字参数整理到一个字典(不是元组)中。
作用域可以理解为一个不可见的字典。
嵌套作用域与闭包。
第7章 更加抽象
面向对象 三原则
- 封装
- 继承
- 多态
封装和多态有些类似,但出发点不同。封装侧重于调用者不必知道方法的具体实现,多态侧重于要使用某个方法时不必去管对象具体属于哪个类型。
这里使用
isinstance
进行类型检查是为了说明一点,类型检查一般来说不是什么好方法,能不用则不用。
因为 isinstance
进行类型检查破坏了代码的多态性。
除非是遗留代码,不然应当使用新式类,在模块或脚本开头使用赋值语句:__metaclass__ = type
Python 并不直接支持私有属性或方法,要表明某个方法是私有方法时,可以在前面加上两个下划线。import
语句会自动忽略前面带有下划线的属性和方法。
尽量避免使用多重继承。
Python 不支持接口,但在调用方法之前可以确定是否存在该方法。
第8章 异常
Python 使用异常对象来表示异常情况。异常对象未被处理或捕捉时,采用回溯(traceback)来终止执行。
raise
语句
异常的捕捉与“上浮(propagate ouf of the functions where the're called)”。如果在发生异常时未提供except语句,异常会上浮(bubble up)到调用该函数的函数中,一直到程序的最顶层。
查看 Python 内建的异常类型:
import exceptions
print dir(exceptions)
捕捉到了异常但是暂时不想处理,可以调用不带参数的 raise
对异常进行“转发”:
try:
// some code
except:
//
raise
一个 try 语句之后可以跟随多个 except 语句,用于捕捉不同类型的异常。
except 语句之后可以将多种类型的异常通过元组的方式列出:
except: (ZeroDivisionError, TypeError, NameError)
在异常处理代码中使用异常对象:
try:
// ...
except: (ZeroDivisionError, TypeError), e:
print e
Python 3.0 中的写法是 except: (ZeroDivisionError, TypeError) as e
try/except 语句可以加上else子句:
try:
// ...
except:
// ...
else:
// ...
这里的 else 只有在没有发生异常的情况下才会被调用。
finally 子句,用于在有异常发生的情况下的清理工作。finally 子句一般用于关闭文件、套接字连接、数据库连接等。
一般来说,使用 try/except 比使用 if/else 更 pythonic!
请求宽恕易于请求许可。
在 Objective-C 中正好相反吗?
第9章 魔法方法、属性和迭代器
这章讲得不是很细。要重读英文版
魔法方法:名字前后带下划线的、具有特殊作用的方法。
用得最多的魔法方法:__init__
调用父类构造方法的两种形式
- Unbound Superclass Constructor (那么 Python 所有的方法都可以当作静态方法来调用?)
class SongBird(Bird):
def __init__(self):
Bird.__init__(self)
// ...
- 使用
super
函数
__metaclass__ = type // super 方法只对新式类有效
class SongBird(Bird):
def __init__(self):
suepr(SongBird, self).__init__()
// ...
注意:Python 3.0 中 调用 super 函数不再需要提供参数。
应该尽量使用新式类。
Python 中的 protocol
序列和映射成员访问规则:__len__(self)
, __getitem__(self.key)
, __setitem__(self.key, value)
, __delitem__(self.key)
property 函数:用于对 get/set 函数进行组织,最多接受4个参数:
property (fget, fset,fdel, doc)
静态方法与类成员方法
静态方法不需要self作为参数,类方法需要提供一个叫做 cls
参数。
正式的说法是,一个实现了
__iter__
方法的对象是可迭代的,一个实现了next
方法的对象是迭代器。
生成成器:包括 yield 语句的函数
生成器推导式(?)
生成器是由两部分组成的:生成器的函数和生成器的迭代器。
Generators are ideal for complex recursive algorithms that gradually build a result.
八皇后问题的例子:要多看几遍才能懂。bitbucket repo
第10章 自带电池
作为“主程序”或作为模块导入其他程序时,变量 __name__
的值是不一样的。可根据 __name__
来确定是否需要执行代码:
if __name__ == '__main__': test()
模块的文件名要和模块名称一致。
包就是一个目录,为了表明该目录是一个包,需要在其中创建一个名为 __init__.py
的文件(模块)。
导入模块的三种方式:
import drawing
:只有__init__
模块中的内容可用。import drawing.colors
:只能通过全名drawing.colors
使用from drawing import colors
:可以通过短名称colors
使用
使用列表推导式查看一个模块里的内容:
import copy
[n for n in dir(copy) if not n.startswith('_')]
使用 __all__
变量,可以列出模块的所有“公有接口(public interface)”,也就是使用 import *
时导入的所有方法。如果模块中没有定义 __all__
变量,那么 import *
会导入其中的所有方法。
import copy
print copy.__all__
查看包的源代码文件路径
import os
print os.__file__
标准库中的实用资源
sys
:argv
、path
os
:environ
、seq
、pathsep
、linesep
fileinput
高级数据结构
集合(Set)、堆(heapq,heap queue)、双端队列(deque, double-end queue)
time 模块
random 模块
shelve 文件存储模块
re 模块:escape()
函数