天堂1111 发表于 2015-12-15 12:00:44

python核心编程--笔记 (转)

python核心编程--笔记11.1 –d   提供调试输出
1.2 –O   生成优化的字节码(生成.pyo文件)
1.3 –S   不导入site模块以在启动时查找python路径
1.4 –v   冗余输出(导入语句详细追踪)
1.5 –m mod 将一个模块以脚本形式运行
1.6 –Q opt 除法选项(参阅文档)
1.7 –c cmd 运行以命令行字符串心事提交的python脚本
1.8 file   以给定的文件运行python脚本
2 _在解释器中表示最后一个表达式的值.
3 print支持类c的printf格式化输出: print “%s is number %d!” % (“python”, 1)
4 print的输入内容后面加逗号, 就会使其输入不换行
5 把输出重定向到日志文件:
logfile = open(“c:/1.log”, “a”);   //打开文件c:/1.log使用a模式..即add, 添加.
print >> logfile, “Fatal error: invalid input!”;   >>为重定向..将print的结果重定向到logfile, 输出内容是”Fatal error: invalid input!”…
logfile.close();//关闭文件流…
6 程序输入: raw_input(“提示字符串”): user = raw_input(“请输入您的姓名”);
7 int(数值)…..将数值字符串转换成整数值…
8 运算符:
8.1 + - * / %是和其他语言相同的加减乘及取模运算.取余运算
8.2 / 在浮点取模中得到的结果是完整的浮点数
8.3 // 在浮点取模中得到的结果是经过舍去运算的结果.
8.4 ** 是乘方
8.5 >>和> 和value方式的enumerate对象
37.4 zip()将多个列表压缩成为一个元组列表…..zip返回的元组列表可以使用足够元组内元素数量的参数来迭代遍历每一个元素, 例如: for a, b, c, d in zip(alist, blist, clist, dlist)
37.5 使用list()和tuple()可以完成列表和元组之间的转换, 但是这种转换是值的转换, 所以他们是==的, 但是不是is的
37.6 extend(列表)方法接受另外一个列表追加到原列表之后
37.7 list.pop(index = -1)list的pop可以弹出指定索引的值
38 处理一组对象的时候, 默认的是创建一个元组, 例如a = 1, 2, 3, 4 实际上是创建了一个元组(1, 2, 3, 4)
39 单独使用del删除一个元组元素是不可行的, 只能通过重组
40 元组的可变性: 元组的某一个元素指向了一个对象, 该对象是可变的, 那么改变该对象就相当于改变了元组的内容, 然而, 真正的我们的元组确实是没有改变的. It’s so wizardly. 为什么呢? 元组内部持有的是对方的引用, 那个对象无论怎么变都还是在那里, 所以, 元组内部的值(内存地址)是没有改变的.
41 函数可以返回多对象, 返回的实际也是一个元组
42 单元素元组使用括号创建时需要在后面显示的加上”, ”, 由于括号被重载作为一个分组操作符了, 在这里会优先使用分组功能, 所以, 返回的总是原始类型
43 相关模块:
43.1 数组array   受限的可变序列类型, 要求所有元素都是相同的类型
43.2 operator   包含函数调用形式的序列操作符, operator.concat(m, n)相当于m+n
43.3 reperl风格的正则查找
43.4 StringIO / cStringIO长字符串作为文件来操作, 比如read(),seek()函数……c版本的速度更快一些
43.5 Textwrap包裹/填充文本的函数
43.6 types   包含python支持的所有类型
43.7 collections高性能容器数据类型
43.8 UserList包含了list对象的完全的类实现, 允许用户获得类似list的类, 用以派生新的类和功能
44 浅拷贝: 拷贝原对象中的内容, 但是新创建对象. 比如一个list的浅拷贝就是把list中元素的引用值拷贝过去…浅拷贝实例: 完全切片操作, 利用工厂函数, 使用copy模块的copy函数
45 深拷贝: 拷贝源对象中的内容, 如果某个属性(或序列中的元素)是可变对象, 把该可变对象的内容也进行拷贝
46 非容器类型对象没有拷贝一说
47 可变参: f(*args1, **args2), 如果关键字可变参不指定key值, 会被作为位置参数和前面的参数放到一个元组中….位置可变参在倒数第二个位置, 关键字可变参在倒数第一个位置.
48 map(function, iterable), 应用function在iterable的每一个元素, 返回值作为新的序列的元素
映射和集合类型(chapter7)1 字典使用keys()获得键的列表, values()获得值的列表, items()获得包含key->value对的元组的列表
2 字典的创建和赋值
2.1 dict = {key: value}
2.2 dict = dict((key, value), (key, value))
2.3 dict.fromkeys(sequence_keys, default_value) 创建一个key是sequence_keys中元素的字典, 所有的value都是default_value, 如果不指定default_value, 默认是None
3 使用dict.has_key()可以判断一个字典中是否有这个键, 该方法在后期python可能弃用, 推荐使用in和not in
4 字典的键必须是可哈希的
5 print中使用到字典的时候, 使用字符串格式化方式是非常优雅的
6 dict1.update(dict2 | tuple_list[, **key=value])
6.1 将dict2字典更新到dict1中
6.2 如果参数是一个元组列表, 将元组列表解析到dict1中(元组列表中每个元组必须有两个元素)
6.3 可以在参数后面跟0—n个关键字参数, 以参数名: value的方式更新到dict1中
7 元素的删除
7.1 del dict[“key”] 删除键是key的条目
7.2 dict.clear()清空字典内的内容
7.3 dict.pop(“name”)删除键是key的条目并返回
8 映射类型操作符
8.1 标准类型操作符: 等比较操作符可以使用, 在比较过程中, 还是调用了字典的cmp方法, 但是, 字典的cmp方法中指示, 首先比较字典的长度, 然后比较键的大小, 最后比较值的大小
8.2 字典查找操作: [], 成员关系操作: in, not in
9 dict工厂函数
9.1 接受不定关键字参数: dict(a = 1, b = 2, c = 3)
9.2 接受字典或关键字参数: 将原有的字典拷贝出来成为一个新的字典(这里使用的浅拷贝, 这里的浅拷贝得到的结果和使用copy函数得到的结果是一样的,但是, copy函数的效率更高)
9.3 dict_instance.copy() 使用已有的字典拷贝一个字典(这里使用的也是浅拷贝)
10 系统内建函数
10.1 len(): 返回字典的key-value对的数目
10.2 hash(): 这个函数不是为字典设计的, 但是它可以判断某个对象是否可以做一个字典的键, 将一个对象作为参数传递给hash(), 会返回这个对象的哈希值.如果对象是不可哈希的, 会返回TypeError, 提示该对象是unhashable的
10.3 sorted(dict):返回dict的所有key排序后的列表
11 dict类型的内建方法
11.1 keys(): 返回字典的所有key的列表
11.2 values(): 返回字典的所有value的列表
11.3 items(): 返回字典的所有key-value的元组的列表
11.4 get(key, default = None):获取字典内key对应的值, 如果没有该key, 返回default指定的默认值
11.5 setdefault(key, default=None): 如果字典中不存在key, 由dict=default为其赋值
11.6 iterkeys(), itervalues(), iteritems() 对应没有iter命名的方法, 这里使用了惰性赋值的迭代器, 节省内存
12 数字作为字典的键的时候, 只要值相同, 就代表相同的键, 比如, 1, 和1.0代表的就是相同的键
13 键必须是可哈希的, 所有的不可变对象都是可哈希的, 可变对象如果在定义中定义了__hash__()方法, 那么就可以作为键
14 如果元组中的值都是不可变类型的, 那么元组也可以作为字典的键
15 集合sets有两种不同的类型, 可变集合set和不可变集合frozenset…可变集合也是不可哈希的…
16 集合中不能有重复的元素, 如果有元素和已有元素重复, 就不会被插入.集合是无序的, 但是, 可以使用排序函数为它排序
17 集合中可以使用的数学符号

18 集合只能使用工厂函数set和frozenset创建
19 访问集合中的数据使用循环, 或者使用成员关系操作符in, not in判断元素是否属于集合
20 更新集合(只能是set, frozenset不能被更新)
20.1 add()添加一个元素
20.2 s.update()接受一个序列类型的参数, 把该序列中有而集合中没有的元素添加到集合中
20.3 s.remove()从集合中移除一个元素
21 集合可用的标准类型操作符
21.1 成员关系: in, not in
21.2 集合等价/不等价: ==, !=
21.3 子集/超集: =
22 集合类型操作符(所有的集合类型)集合互相操作的时候, 最后产生的集合是可变集合还是不可变集合取决于第一个参与操作的集合的类型
22.1 联合 |
22.2 交集 &
22.3 差补/相对补集-A-B就返回属于A 但不属于B的元素集合
22.4 对称差分   ^A^B = A-B + B-A
23 可变集合特有的操作符
23.1 |=相当于update方法, 并集赋值
23.2 &=相当于intersection_update()方法, 交集赋值
23.3 -=   相当于difference_update()方法, 差集赋值
23.4 ^=相当于symmetric_difference_update()方法, 对称差分更新
24 集合类型的内部方法:
24.1 s.issubset(t)判断s是不是t的子集
24.2 s.issuperset(t)判断s是不是t的超集
24.3 s.union(t)   返回一个新集合, 该集合是s和t的并集
24.4 s.intersection(t)返回一个新集合, 该集合是s和t的交集
24.5 s.difference(t)返回一个新集合, 该集合是s的成员, 但不是t的成员, 即返回s不同于t的元素
24.6 s.symmetric_defference(t)返回所有s和t独有的(非共同拥有)元素集合
24.7 s.copy()返回一个s的浅拷贝, 效率比工厂要好
25 可变集合特有的方法: add, remove, discard, pop, clear, 这些接受对象的方法, 参数必须是可哈希的
26 那些和操作符提供相同功能的函数, 有着更强的处理能力, 因为运算符两边的操作数必须都是集合, 然而函数可以接受任何的可迭代类型.
条件和循环(chapter8)1 如果循环体, 或条件语句体只有一句, 可以和头写在同一行.
2 字典的搜索速度要比for, if, while等快得多
3 True and object, 返回object, True or object 返回True, 因此可以使用expression and out1 or out2 模拟三元操作符
4 python提供的三元操作: X if C else Y, 如果c输出x, 否则输出y
5 xrange()不会在内存中创建列表的完整拷贝, 只被用在for循环中.
6 reversed()和enumerate()内建函数返回的是一个迭代器
7 迭代器的优点
7.1 提供了可扩展的迭代器接口
7.2 对列表迭代带来了性能上的增强
7.3 在字典迭代中性能提升
7.4 创建真正的迭代接口,而不是原来的随机对象访问
7.5 与所有已经存在的用户定义的类以及扩展的模拟序列和映射的对象向后兼容
7.6 迭代非序列集合(例如映射和文件)时, 可以创建更简洁的代码
8 迭代器工作原理: next()方法取出元素, 元素全部取完后触发StopIteration异常, for可以根据异常结束循环
9 any(), all()用来判断序列或迭代器中元素的真假, any为或操作, all为与操作
10 iter(iterable) 用来创建一个迭代器
11 文件的迭代器中调用next方法, 默认会调用readline方法.如果直接使用for line in file就可以创建一个默认的文件迭代器.
12 在迭代的时候, 不要尝试改变可变对象
13 列表解析:
13.1 lambda, 动态创建函数
13.2 map(function, sequence), 对sequence的每一个元素应用function, 返回一个新的列表
13.3 filter(function, sequence), 对sequence的每一个元素应用function, 某个元素应用该function后如果返回false, 该元素将被从最后返回的列表中过滤掉
13.4 列表解析中可以使用多个循环, 来达到生成矩阵或多维序列的目的..例如【(x, y) for x in range(5) for y in range(3)】 越靠后的循环就相当于普通循环中的内层循环
14 生成器
14.1 生成器表达式和列表解析表达式是一样的, 但是生成器表达式没有中括号, 单独使用的时候, 使用圆括号, 作为参数的时候, 不需要圆括号
14.2 生成器表达式可以被用作迭代
14.3 生成器表达式是lazy的
14.4 示例: 获取文件的最长的行的长度: logest = max(len(line.strip()) for line in file)
文件和输入输出(chapter9)1 文件只是连续的字节序列
2 file_object = open(file_name, access_mode = ‘r’, buffering = -1) mode有r, w, a, 分别表示读取, 写入, 追加.U模式代表通用换行符支持
2.1 使用r, U打开的文件必须是已经存在的,使用w打开的文件如果存在, 首先清空…使用a模式打开的文件是为追加数据做准备, 所有写入数据被追加到文件末尾.+代表可读可写, b代表二进制访问… POSIX兼容的Unix系统中, ‘b’是可有可无的, 因为它们把所有的文件都当作二进制文件.包括文本文件
2.2 如果在mode中要使用b, b不能作为第一个字符出现
2.3 buffering, 表示缓冲区大小, 0表示不缓冲, 1表示只缓冲一行数据, 其他大于1的值表示使用定值作为缓冲区大小.不提供该参数或给定负值代表使用系统默认的缓冲机制
2.4 访问模式:
2.4.1 r只读方式打开
2.4.2 rU或Ua读方式打开, 同时提供通用换行符支持
2.4.3 w写方式打开
2.4.4 a追加模式打开, 必要时创建新文件
2.4.5 r+读写方式打开
2.4.6 w+读写方式打开
2.4.7 a+读写方式打开
2.4.8 rb二进制读模式打开
2.4.9 wb二进制写模式打开
2.4.10 ab二进制追加模式打开
2.4.11 rb+二进制读写模式
2.4.12 wb+二进制读写模式
2.4.13 ab+二进制读写模式
3 file()内建函数和open的使用方式一样…但是推荐使用open, 除非特定的要处理文件对象时, 使用file()内建函数
4 通用换行符支持: 任何系统下的文件, 不管换行符是什么, 使用U模式打开时, 换行符都会被替换为NEWLINE(\n)
5 python默认打开UNS, 如果不需要通用换行符支持, 在运行configure脚本时, 可以使用—without-universal-newlines 开关关闭.
6 文件方法:
6.1 输入
6.1.1 read(size=-1): 直接读取字节到字符串中, 最多读取给定数目个字节.不指定size参数, 或size值为负, 文件将被读取到末尾.
6.1.2 readline(size = -1)size为负数或不指定, 读取至行末, 如果指定了其他的size值, 读取size个字节   读到的换行符不会自动去掉, 而把这个操作留给程序员, 使用strip去掉
6.1.3 readlines(sizhint = -1)sizhint和size功能相同, 如果指定, 会读取sizhint个字节, 实际读取值可能比sizhint较大, 因为需要填充缓冲区
6.1.4 file.xreadlines()和xreadlines.xreadlines(file) 是一种更高校的文件读取, 一次读取一块, 而不是一次读取所有行, 但是, 由于iter取代了该功能, 所以会被废弃.
6.2 输出
6.2.1 write()把含有文本数据或二进制数据块的字符串写入到文件中
6.2.2 writelines() 接受一个字符串列表作为参数, 将他们写如文件, 行结束符不会自动加入, 如果需要, 必须在调用writelines之前手动在每行结尾加上换行符
6.2.3 seek(offset, whence)随机文件访问, 第一个参数offset表示偏移量, 第二个参数表示位置, 即第一个参数相对哪里去偏移
6.3 迭代: 直接似乎用for循环迭代
6.4 其他:
6.4.1 close()关闭文件结束对它的访问.垃圾回收机制也会在文件对象的引用计数降至0的时候自动关闭文件.
6.4.2 fileno()返回打开文件的描述符…是一个整数, 可以用在如os模块的read方法等一些底层操作上.
6.4.3 flush()方法直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入.
6.4.4 tell()方法返回文件的当前位置, 对应seek方法的offset参数
6.4.5 isatty() 是一个布尔内建函数, 当文件是一个类tty设备时返回true, 否则返回false.
6.4.6 truncate()方法将文件截取到当前文件指针位置或者到给定size, 以字节为单位
6.4.7 next()返回文件的下一行
7 os模块的重要属性
7.1 linesep   跨系统的分隔行的字符
7.2 sep   分割文件路径名的字符串( / \   路径内的不同级分割)
7.3 pathsep   分割文件路径的字符串(;多个路径分割)
7.4 curdir   当前工作目录的字符串名称(. )
7.5 pardir当前工作目录的父目录的字符串名称(.. )
8 文件的内建属性:
8.1 name文件名, 打开文件或使用file()工厂的时候传递的文件名参数
8.2 mode打开模式
8.3 closed是否已经关闭
8.4 encoding   编码方式, None表示使用系统默认的编码
8.5 newlines未读取到行分隔符时为None, 只有一个种行分割符时为一个字符串, 当文件有多种类型的行结束符时, 则为一个包含所有当前遇到的行结束符的列表
8.6 softspace0表示在输出一数据后, 要加上一个空格符, 1表示不加
9 标准文件, sys模块下的stdin, stdout, stderr分别是标准输入文件(键盘), 标准输出文件(缓冲的屏幕输出), 标准错误(到屏幕的非缓冲输出)这三个文件是预先打开的, 可以直接使用
10 sys.argv是命令行参数的列表, 列表中第一个是当前python脚本的名称, 后面分别是python脚本在命令行下被调用时传入的参数, 类似于java的main方法接受的参数, len(sys.argv)是命令行参数的个数
11 其他提供命令行参数的辅助处理模块:
11.1 getopt模块, 简单的命令行参数处理
11.2 optparse模块, 复杂的命令行参数处理.
12 os模块: 所有操作系统对外的门面, 主要提供删除/重命名文件, 遍历目录树, 管理文件访问权限等功能
12.1 文件处理
12.1.1 mkfifo()/mknod()创建命名管道/创建文件系统节点
12.1.2 remove()/unlink()删除文件, 指定路径为参数进行删除, 如果文件不存在会抛出异常
12.1.3 rename()/renames()重命名文件, 接受旧文件路径和新文件路径, 进行名字的修改, 这里可以通过指定新的路径达到文件移动的目的. 没有发现renames和rename的区别
12.1.4 stat()返回文件信息, 包含文件的mode, 编号, 用户(创建者, 所有者, 组), 时间等信息
12.1.5 symlink()创建符号链接   ….已经废除???
12.1.6 utime()更新时间戳
12.1.7 tmpfile()创建并打开(‘w+b’)一个新的临时文件没有参数, 直接获取一个临时文件
12.1.8 walk(top, ]]) 生成一个目录树下的所有文件名.
12.1.8.1 该方法用于生成目录树下的所有子文件名, 该方法返回一个生成器, 遍历生成器可以得到一个三个元素的元组(dirpath, dirnames, filenames)
12.1.8.2 返回元素元组中的dirpath是top的目录名, dirnames是top下所有子目录的文件名集合, 不包含当前目录.和上级目录.., filenames是top下的所有的非目录类型的文件的名字集合
12.1.8.3 walk返回元组中的名字集合可以使用os.path.join(dirpath, name)得到一个文件或目录的全路径.
12.1.8.4 walk返回的生成器包含了top目录之下所有子孙目录的内部结构
12.1.8.5 walk的第二个参数topdown指示了对该目录树的遍历是否采用自上而下的方式, 默认是True
12.1.8.6 walk的第三个参数是指示错误发生时是否处理, 接收的是一个回调函数, 函数会得到一个参数OSError的实例
12.1.8.7 walk的第四个参数是指示是否遍历link类型指向的目录, 默认是false, 但是, 如果你设置了followlinks=True, 并有一个link是指向它的父亲或更高辈分的目录, 就会产生一个无穷递归.
12.1.8.8 注意:如果使用walk的时候传递了一个相对路径, 在重新开始walk之前, 不要改变工作目录..当前工作路径的改变会导致walk停止工作
12.2 目录/文件夹处理
12.2.1 文件的fileno()返回该文件的文件描述符
12.2.2 chdir()/fchdir()改变当前工作目录/通过一个文件描述符改变当前工作目录
12.2.3 chroot()改变当前进程的根目录
12.2.4 listdir()列出指定目录的文件, 返回参数指定的路径下的所有文件和目录, 不包括当前目录.和父亲.., 也不进行递归
12.2.5 getcwd()/getcwdu()返回当前工作目录/功能相同, 但返回一个unicode对象
12.2.6 mkdir()/makedirs()创建目录/创建多层目录, 接受两个参数, 一个表示路径, 一个表示模式(权限???)mkdir()只能用于创建一级目录, 如果父目录不存在会抛出异常, 而makedirs()会向上递归的创建目录
12.2.7 rmdir()/removedirs()删除目录/删除多层目录rmdir删除一个目录或文件, removedirs()则递归删除一个目录树, removedirs()是一个难懂的函数, 指定一个父亲无法删除父亲下的所有孩子, 反而由孩子删除了自己的父亲和祖辈
12.3 访问/权限
12.3.1 access()检验权限模式, 两个参数, 第一个是路径, 第二个是模式, 模式可以是F_OK, 用来检测路径是否存在, R_OK用来检测是否可读, W_OK用来检测是否可写, X_OK用来检测是否可执行.返回布尔值表示检验结果
12.3.2 chmod()改变权限模式接受两个参数, 第一个是路径, 第二个是模式, 模式在stat模块下定义, 是一些数字类型代表的模式, 主要是针对linux下的权限控制, 尽管windows下也支持这个方法, 但是, 只有stat.S_IREAD, stat.S_IWRITE才会起到真正的作用.
12.3.3 chown()/lchown()改变owner和group Id / 功能相同, 但不会跟踪链接….或许这个方法windows平台不支持??? 接受三个参数, 第一个是路径, 第二个是用户id, 第三个是组id
12.3.4 umask()设置默认权限模式 接受一个数字类型的参数, 设置新的默认权限模式, 并返回之前的权限模式.
12.4 文件描述符操作
12.4.1 open()底层的操作系统open
12.4.2 read()/write()根据文件描述符读取/写入数据
12.4.3 dup(file_descriptor)/dup2(file_descriptor, file_descriptor2)dup返回file_descriptor的复制品, dup2则是把file_descriptor复制到file_description2
12.4.3.1 每个进程在进程表中有一个记录项, 每个记录项中有一张打开文件描述符表, 可以看作是一个矢量, 每个描述符占用一项, 与每个文件描述符相关联的是:
12.4.3.1.1 文件描述符标志
12.4.3.1.2 指向一个文件表项的指针
12.4.3.2 内核为所有打开文件维持一张文件表, 每个文件表项包含
12.4.3.2.1 文件状态标志(读, 写, 增写, 同步, 非阻塞等).
12.4.3.2.2 当前文件位移量
12.4.3.2.3 指向该文件v节点表项的指针
12.4.3.3 习惯上, 标准输入(STDIN_FILENO)的文件描述符是0, 标准输出(STDIN_FILENO)的文件描述符是1, 标准错误(STDERR_FILENO)的文件描述符是2
12.4.3.4 文件描述符是非负整数, 打开现存文件或新建文件时, 内核会返回一个文件描述符, 读写文件也需要使用文件描述符来指定待读写的文件
12.4.3.5 文件描述符的有效范围是0 ---- open_max, 一般, 每个进程最多打开65个文件, freebsd5.2.1, mac os x 10.3和solaris9则支持每个进程打开最多文件数和内存, int的大小, 管理员设定有关, linux2.4.22强制规定最多不超过1048576个.
12.4.3.6 fdopen(file_descriptor[, mode[, fuffer_size]])通过指定文件描述符, 模式, 缓冲区大小打开一个文件.由于缓冲区的存在, 最后需要显示的flush()一下以清空缓冲区
12.4.3.7 dup2(fd, fd2)表示fd和fd2共享同一个文件表项, 也就是说他们的文件表指针指向了同一个文件表项, 因此他们也就是共享了相同的文件i/o…第一个参数必须是已经存在的并且打开的合法的文件描述符, 而第二个参数可以是任意的文件描述符
12.4.3.8 dup(fd)返回一个和文件描述符fd同样的文件描述符, 这里是为了备份文件描述符, 当一个文件描述符使用dup2进行重定向之前, 我们应该首先用dup拷贝一份出来备份, 需要恢复的时候进行再次重定向.它的语义是:返回一个新的文件操作符, 和原来的文件操作符fd共享一个文件表项
12.5 设备号
12.5.1 makedev()从major和minor设备号创建一个原始设备号
13 os.path模块的路径名访问函数
13.1 分隔
13.1.1 basename()去掉目录路径, 返回文件名
13.1.2 dirname()去掉文件名(自己的名字, 如果是文件夹就是文件夹名), 返回目录路径
13.1.3 join()将分离的各部分组合成一个路径名…可以接受不定数量个参数.
13.1.4 split()返回一个元组, 第一个元素是目录名, 第二个元素是文件名(或最后一层的文件夹名)
13.1.5 splitdrive()返回一个元组, 第一个元素是该路径所属的设备号(比如C盘), 第二个元素是相对该设备的相对路径
13.1.6 splitext()返回一个元组, 第一个元素是该路径的全路径(不含文件后缀名, 如果末级是文件夹, 第二个元素为空), 第二个元素是文件的后缀名
13.2 信息
13.2.1 getatime()返回最近访问时间这里的返回时间的方法都是返回int型的秒数
13.2.2 getctime()返回文件创建时间
13.2.3 getmtime()返回最近文件修改时间
13.2.4 getsize()返回文件大小
13.3 查询
13.3.1 exists()判定文件/目录是否存在
13.3.2 isabs()判定路径是否是绝对路径
13.3.3 isdir()判定路径是否存在且为一个目录
13.3.4 isfile()判定路径是否存在且为一个文件
13.3.5 islink()判定路径是否存在且为一个符号链接
13.3.6 ismounts()判定路径是否存在且为一个挂载点
13.3.7 samefile(path1, path2)判定两个路径名是否指向同一个文件
14 永久存储模块
14.1 pickle和marshal: 一组最小化永久性存储模块(序列化). 可以用来转换并存储python对象.是将python的对象转换成一个二进制数据集合保存起来, 可以通过网络发送, 然后重新把数据集合恢复成原来的对象格式, 也就是java中的序列化.
14.2 marshal和pickle模块的区别在于marshal只能处理简单的python对象(数字, 序列, 映射, 代码对象), 而pickle还可以处理递归对象, 被不同地方多次引用的对象, 以及用户定义的类和实例...
14.3 pickle模块还有一个增强的版本叫cPickle
14.4 *db*系列的模块使用传统的DBM格式写入数据… python提供了dbhash/bsddb, dbm, gdbm, dumbdbm等多个DBM实现.如果不确定, 使用anydbm模块, 它会自动检测系统上已经安装的DBM兼容模块, 选择’最好’的一个.dumbdbm模块是功能最少的, 没有其他模块可用时, anydbm才会选择它….这些模块的不足指出在于他们只能存储字符串, 不能对python对象进行序列化
14.5 shelve模块使用anydbm模块寻找合适的DBM模块, 然后使用cPickle完成对储存的转换过程. shelve模块允许对数据库文件进行并发的读访问, 但不允许共享读/写访问.

14.6 pickle的使用
14.6.1 dump(obj, file, protocol = None): 接受一个数据对象和一个文件, 把数据对象以特定的格式保存到给定的文件里.
14.6.2 load(file)从文件中取出已经保存的对象.
15 相关模块:
15.1 base64二进制字符串和文本字符串之间的编码/解码操作
15.2 binascii二进制和ascii编码的二进制字符串间的编码/解码操作
15.3 bz2访问BZ2格式的压缩文件
15.4 csv访问csv文件(逗号分割文件)
15.5 filecmp   用于比较目录和文件
15.6 fileinput提供多个文本文件的行迭代器
15.7 getopt/optparse提供了命令行参数的解析/处理
15.8 glob/fnmatch提供Unix样式的通配符匹配功能
15.9 gzip/zlib   读写GNU zip(gzip)文件(压缩需要zlib模块)
15.10 shutil提供高级文件访问能力
15.11 c/StringIO   对字符串对象提供类文件接口
15.12 tarfile读写TAR归档文件, 支持压缩文件
15.13 tempfile   创建一个临时文件(名)
15.14 uu格式的编码和解码
15.15 zipfile用于读取ZIP归档文件的工具
16 fileinput模块遍历一组输入文件, 每次读取它们内容的一行, 类似Perl语言中的不带参数的操作.
错误和异常(chapter10)1 常见异常:
1.1 NameError: 尝试访问一个未声明的变量
1.2 ZeroDivisionError: 除数为0
1.3 StntaxError: python解释器语法错误, 这个异常是唯一一个编译时错误.
1.4 IndexError:请求的索引超出序列的范围
1.5 KeyError:请求一个不存在的字典关键字
1.6 IOError: 输入/出处错误
1.7 AttributeError:尝试访问一个未知的对象属性错误
1.8 ValueError:值错误(参数值错误)
1.9 TypeError:类型错误(参数类型错误)
2 异常的检测, 抓取处理:
2.1 try ---- except ---- finally
2.2 和java的异常处理类似, 但是这里不用throws, 只要不显式的捕获, 就向上抛出
3 同一个except子句中可以处理多个异常: except (Exception1[, Exception2, …, Exceptionn])[, reson]:   需要注意的是, except在处理多个异常的时候, 需要把多个异常放在一个元组中.
4 所有异常的基类是Exception, 所以, 可以使用Exception捕获所有的异常…当然, 也可以使用裸except语句捕获多数的异常
5 异常发生时, 可以使用sys.exc_info()或得到当前的系统执行信息, 得到的结果元组类似下面的格式: (, IndexError('list index out of range',), )第一个元素表明异常的类型, 第二个元素是异常, 第三个是堆栈信息
6 有些异常不是由于错误条件引起的, 比如SystemExit, KeyboardInterupt…SystemExit是由于当前Python应用程序需要退出引起的, KeyboardInterupt则代表用户按下了ctrl-c, 想要关闭python
7 python2.5之后的异常体系结构
- BaseException
|- KeyboardInterrupt
|- SystemExit
|- Exception
|- (all other current built-in exceptions) 所有当前内建异常
8 异常参数是可以被忽略的, 其中包含的是对导致异常的代码的诊断信息, 异常参数通常会自身组成一个元组, 并存储为类实例(异常类的实例)的属性.
9 带else的try(如果try块中没有发生except的异常, 执行else)
try:
   code_block
except (Exception …), reason:
   code_block
else:
   code_block
finally:
   code_block
10 with语句用于上下文管理和资源分配
with context_expression :
   with_suite
         上面的语句是with的标准语法, 表示通过context_expression表达式创建一个上下文环境, 并将其交给句柄var, 在with_suite中可以使用这个上下文环境, with会自己去处理上下文环境的准备工作和收尾工作(无论是异常发生还是执行结束)
11 python2.6开始支持with语法, 支持的模块有:
11.1 file
11.2 decimal.Context
11.3 thread.LockType
11.4 threading.Lock
11.5 threading.RLock
11.6 threading.Condition
11.7 threading.Semaphore
11.8 threading.BoundedSemaphore
11.9 例如:
with open(‘c:\\1.txt’, ‘r’) as f:
         #file operate
这样就会自动管理文件的打开关闭等操作和异常处理
12 上下文表达式和上下文管理器(可以通过自定义自己的类, 实现系统方法__enter__()和__exit__()来定义自己的上下文对象/上下文管理器):
12.1 context_expression 用来获得一个上下文管理器…上下文管理器的职责是提供一个上下文对象.通过__context__()方法实现, 该方法返回一个上下文对象, 用于在with语句块中处理细节.   上下文对象本身就可以是上下文管理器.. 所以context_expression既可以是一个真正的上下文管理器, 也可以是一个自我管理的上下文对象, 在后一种情况时, 上下文对象荏苒有__context__(), 返回其自身.
12.2 获得一个上下文对象之后, 就会调用它的__enter__()方法, 它将完成with语句块执行前的所有准备工作, with语法中的as后面的句柄, 就是通过__enter__()方法的返回值来赋值的.如果没有as子句, 就会丢弃返回值
12.3 执行with语句块,
12.4 with语句块执行结束后, 哪怕是由于异常结束, 都会调用上下文对象的__exit__()方法…__exit__()方法接受三个参数, 如果with语句块正常结束, 三个参数全部都是None, 如果发生异常, 得到的三个参数对应sys.exc_info()得到的元组的三个元素(类型—异常类, 值—异常实例, 回朔—traceback)
12.5 contextlib模块中是关于上下文管理的一些实现
13 触发异常使用raise ]], 第一项是异常类, 第二项是参数(有多个参数使用元组), 最后一项是回朔信息(堆栈)
13.1 通常, 错误的参数中指出错误的原因子串, 错误编号, 错误地址等.也可以使用raise
13.2 如果给定的是一个异常实例, 而发生的异常不是该异常类指示的异常, 那么会根据异常类实例的参数, 重新创建一个实际发生的异常的实例
13.3 raise的语法:
13.3.1 raise exception_class: 触发一个异常, 从exception_class生成一个实例, 不包含任何异常参数
13.3.2 raise exception_class(): 同上
13.3.3 raise exception_class, args同上, 但是提供了异常参数, 参数也可以是一个元组
13.3.4 raise exception_class(args): 同上
13.3.5 raise exception_class, args, traceback同上, 但提供一个追踪对象traceback供使用
13.3.6 raise exception_class, instance: 通过实例触发异常(通常是exception_class的实例):如果实例是exception_class的子类实例, 那么这个新异常的类型会是子类的类型. 如果实例既不是exception_class的实例也不是它的子类的实例, 那么会复制此实例作为异常参数去生成一个新的exception_class的实例
13.3.7 raise instance: 通过实例触发异常, 异常类型是实例的类型
13.3.8 raise string:过时的, 触发字符串异常
13.3.9 raise string, args: 同上, 但触发伴随着args
13.3.10 raise string, args, traceback: 同上, 但提供了一个追踪对象供使用
13.3.11 raise(python1.5新增): 重新触发前一个异常, 如果之前没有发生异常, 触发TypeError
14 断言: assert expression[, arguments]判断expression表达式, 得到断言的真假, 如果真不做任何操作, 如果是假, 触发AssertionError, arguments是在触发AssertionError时传递给异常的参数.
15 相关模块:
15.1 exceptions:内建异常, 不用导入这个模块
15.2 contextliba:为使用with语句的上下文对象工具
15.3 sys包含各种异常相关的对象和函数(sys.ex*)
函数和函数式编程(chapter11)1 过程只处理一些操作, 而没有返回值, 函数则会经过一系列处理返回一些数据. python的过程就是函数
2 关键字参数: 调用函数时按照函数定义时指定的形式参数名=实参句柄的方式指定实参值, 这样的参数就叫关键字参数
3 函数属性不能在函数的声明中访问, 因为函数体还没有被创建, 但是当函数体创建完毕之后, 就可以访问了.
4 python2.1中引入了内部函数的支持机制, 可以在一个函数体内直接定义另一个函数, 内部函数的生命域在父亲方法内.
5 函数的装饰器: 和java中的注解语法一致, 以@开头, 接下来是装饰器函数的名字和可选的参数, 接下来是其修饰的函数
@decorator(decorator_option_arguments)
def function2bedecoratedname(func_arguments):
5.1 没有装饰器之前, 使用绑定的方式将方法注册成为类方法或静态方法:
5.1.1 object.function = staticmethod(function)或在类内部直接function = staticmethod(function)
5.1.2 object.function = classmethod(function) 或在类内部直接function = classmethod(function)
5.2 使用装饰器的语法
5.2.1 静态方法
@staticmethod
def function():
5.2.2 类方法
@classmethod
def function():
5.2.3 带参数的装饰器
@deco1(deco_arg)
@deco2
def func():
就相当于做了
func = deco1(deco_arg)(deco2(func))
5.2.4 装饰器其实就是函数, 装饰器接受函数对象, 并对函数对象进行包装处理, 就相当于java中的aop, 可以使用装饰器做一些日志, 安全性检查等通用型的功能
def mydecorator(func):
         def wrappedFunc():
                   print ‘log is recorded’
                   return func()
         return wrappedFunc

@mydecorator
def f():
         print ‘Hello decorator’

print f()
5.2.5 装饰器的注意点:
5.2.5.1 必须定义一个内部函数名字是wrappedFunc
5.2.5.2 装饰器函数返回的是内部函数wrappedFunc的引用(或别名)
5.2.5.3 wrappedFunc()函数包装器所接受的参数就是被装饰函数的参数列表
5.3 装饰器可以有多个, 每行一个, 按照顺序写就可以了, 其实装饰器就相当于调用了对应的装饰器函数, 对于多个装饰器, 就类似数学上的函数嵌套. (g · f)(x) = g(f(x))
5.4 参数
5.4.1 位置参数, 普通的参数
5.4.2 默认参数, 有默认值的参数
5.4.3 关键字参数, 针对调用时, 使用参数名=值的方式调用的
6 使用*和**调用函数
6.1 *, 将用星号指定的实参转换成一个元组, 元组的每一个元素作为一个参数进行传递. 例如a = func(*a)则func接收到了4个参数.
6.2 **, 用两个星号指定的实参必须是字典类型, 而且字典的键必须是str, 这样传递的参数实际上是以字典中的数据得到了N个关键字参数
7 可变参
7.1 位置可变参使用*argument_name定义, 函数内部得到的将是一个元组.
7.2 关键字可变参使用**argument_name定义, 函数内部得到的将是一个字典.
8 匿名函数与lambda: 使用lambda 参数列表: 表达式的方式可以创建一个匿名函数, lambda构建的函数可以使用可变参.   优点在于绕过了函数的栈分配, 性能得到了提升(测试了10^9数量级次数的空函数调用, 性能提升了1%左右)
9 内建函数
9.1 apply(func[, nkw][, kw]): 用可选的参数来调用func, nkw是非关键字参数, kw是关键字参数, 返回值就是func调用之后的返回结果
9.2 filter(func, sequence): 调用一个布尔函数func迭代遍历序列中的每个元素, 返回一个func返回True的元素的序列.
9.3 map(func, seq1[, seq2…]): 将函数func作用于给定序列中的每个元素, 并用一个列表来提供返回值, 如果func为None, func就表现为身份函数(id), 返回一个含有每个元素中元素集合的n个元组的列表
9.3.1 提供了多少个seq参数, func就接受多少个参数.
9.3.2 如果func存在, 将各个列表的值按顺序传入到func中, 返回的结果被组成一个新的列表作为map的返回.
9.3.3 如果func是None, 返回各个列表的类似压缩得到的元组的列表, 这里的压缩不同于zip, 是类似sql中的外联接的模式.
9.4 reduce(func, seq[, init]): 将二元函数作用于seq序列的元素, 每次携带一对(先前的结果以及下一个元素), 连续的将现有的结果和下一个值作用在获得的随后的结果上, 最后减少序列为一个单一的返回值, 乳沟初始值init给定, 第一个比较会是init和第一个元素而不是序列的前两个元素.有一点类似递归调用
10 引入一个模块的时候可以起一个别名: from module_name import attribute_name as alias
11 偏函数:使用functools模块中的partial()函数创建偏函数, 第一个参数是基函数的引用, 后面跟随基函数的调用中要使用的一些默认值…这里还可以使用关键字参数调用的方式:
toDecimal = partial(int, base = 2)
调用的时候, 只需要指定在partial中没有指定的参数, 比如: toDecimal(‘101010’)
由于在partial中指定的这些固定的参数是在参数列表的最左边, 所以, 如果不使用关键字参数, 可能会导致参数顺序错误.
12 在函数体内使用global关键字可以使全局变量的变量名在函数体内获得全局变量的引用, 在函数体内对全局变量的改变会影响全局变量, 例如:
a = 100
def f():
         global a
         a += 300
         print a
得到的输出会是400, 并且, 全局变量a也被修改为400
注意: 使用global语法, 必须是在该全局变量名第一次在函数体内被使用之前
13 嵌套函数的内部变量作用域为自己的函数体(包含自己的内部子孙函数).在函数体内可以使用的变量域为自己的所有父辈中的变量.
14 闭包: 将内部函数自己的代码和作用于以外的外部函数的作用结合起来, 在一个独立的作用域中, 多用于安装计算, 隐藏状态, 函数对象和作用于中随意切换, 回调.
14.1 自由变量: 定义在外部函数内(非全局变量), 但是由内部函数引用或者使用的变量.
14.2 闭包: 如果在一个函数内, 对在外部作用域的变量(自由变量)进行引用, 那么这个内部函数就被认为是闭包(closure)
14.3 闭包完成的功能很像类.
14.4 闭包将内部函数自己的代码和作用域以外的外部函数作用结合起来…闭包的词法变量不属于全局名字空间域也不属于局部的, 而是属于其他的名字空间, 带着”流浪”的作用域.但是, 这又不同于对象, 对象的变量存活在对象的名字空间, 而闭包变量存活在一个函数的名字空间和作用域.
14.5 闭包的语法:
14.5.1 定义
def out_function(arg1, arg2, arg3……)://定义一个外部函数
         args = //将要作为自由变量的参数放到一个可变对象中.
         def inner_function(self_arg)://定义一个内部函数, 这里可以接受自己的参数
                   args += args + self_arg//改变自由变量, 上面将自由变量放到一个可变对象中就是为了能够保存这种改变.
                   return args//返回修改后的自由变量值
         return inner_function//返回内部函数
14.5.2 调用
closure1 = out_function(1, 2, 3)//得到一个闭包(调用外部函数, 返回了内部函数的引用, 实际上就形成了一个闭包, 这个闭包的作用域内持有了外部函数内定义的args自由变量和内部函数本身)
closure2 = out_function(4, 5, 6)//得到一个闭包
closure1(100)//调用闭包局部的实参是100
closure2(200)//调用闭包返回的
14.6 调用闭包返回的结果很类似调用对象的方法, 但是, 闭包是一种能够有自己的独立作用域的方法, 而对象则是类实例.
14.7 得到一个闭包的实例(实际上就是一个方法), 查看它的func_closure属性, 可以查看该闭包含有的自由变量.
14.8 一个闭包和装饰器结合的绝妙的例子见python-15-function下的closureAndDecorator4Log.py
14.9 lambda定义的函数作用域, 生命周期和普通函数是一致的, lambda也可以不指定参数, 也可以使用全局或外部变量.
14.10 递归: 一个超级短的递归阶乘函数: f = lambda n: n == 1 and 1 or (n == 2 and 2 or n * a(n - 1))
15 生成器: 生成器使用生成器表达式创建, 和列表解析表达式语法相同, 使用圆括号包裹.也是使用next方法, 完成遍历之后抛出StopIteration异常.
15.1 定义: 挂起返回出中间值并多次继续的协同程序成为生成器.
15.2 生成器语法:
def mygenerator(arr):
         for i in arr:
                   yield i
15.3 生成器的创建使用了yield语法, 在调用next方法的时候, 返回下一个yield指示的值, 并让生成器在这个位置停留.
15.4 当然, yield也可以指示做某一个动作之后停止.甚至还允许yield指示的动作返回的是一个None
15.5 生成器适用于较大的数据场合.
15.6 生成器的创建函数中不能有return
15.7 生成器还可以接收外部传送回来的数据进行交互.在外部调用生成器的send方法可以向生成器发送数据, send方法接受一个参数, 这个参数的值就是yield argument_name词法的返回值.send方法返回的是经过处理之后到下一次yield的值, 其实是和调用next()方法的返回值是一样的, 不过这次是经过了send进来的数据的处理方式.
def counter(start):
   count = start
   while True:
            input = yield count
            if input:
                     count += input
            else:
                     count += 1
模块(chapter12)1 影响python的环境变量是PYTHONPATH, 这个是指定python的脚本路径的环境变量
2 运行时指定python的脚本路径通过访问修改sys.path来实现
3 sys.modules可找到当前导入(import)了哪些模块和它们来自哪些地方, sys.modules是一个字典, 模块名是key, 物理地址是value
4 名称空间: 名称(标识符)到对象的映射
4.1 改变一个名字的绑定叫重新绑定
4.2 删除一个名字叫做解除绑定
4.3 执行期间有两个或三个活动的名称空间, 全局名称空间和内建名称空间是固有的, 局部名称空间是不断变化的.
4.4 从名称空间访问名字依赖于它们的加载顺序
4.5 python解释器首先加载内建名称空间. 内建名称空间由__builtins__模块中的名字构成. 然后加载全局名称空间, 在模块开始执行后变成活动名称空间…… 此时, 我们就有了两个活动的名称空间.如果在运行期间调用了一个函数, 就创建出第三个名称空间, 也就是局部名称空间.也可以使用globals()和locals()内建函数判断出某一个名字属于那个名称空间
4.6 名称空间和变量作用域:

4.7 无限空间: 指定一个名字之后, 如果名字指向的是一个名字空间, 都可以使用.语法为其添加属性
5 导入模块的顺序:使用空行分割三种不同类型的导入
5.1 python标准库
5.2 python第三方库
5.3 python应用程序自定义模块
6 from module import name1, name2…
7 from module import name1 as alias1, name2 as alias2
8 执行import语句进行导入的时候, 被导入的模块的顶层代码将会被执行, 并且, 这种执行只有一次(该模块在整个python程序进程或pythonVM中第一次被导入时)
9 将已经安装的模块作为脚本执行, 使用[$ foo.py]
10 from-import导入方式并不是良好的编程风格, 这会污染当前名称空间
11 from __future__ import new_feature 是用来导入python的新特性的, 必须使用from-import的方式.
12 警告框架: Warning直接从Exception继承, 是所有警告的基类: UserWarning, DeprecationWarning, SyntaxWarning, RuntimeWarning
13 可以从指定zip文件名到sys.path, 从zip文件中直接导入模块
14 *新的导入钩子:
14.1 查找器: 接受一个参数: 模块或包的全名, 查找器实例负责查找模块
14.2 载入器: 如果查找器查找成功将会返回一个载入器对象.载入器会将模块载入到内存.
14.3 查找器和载入器实例被加入到sys.path_hooks
14.4 sys.path_importer_cache用来保存这些实例.
14.5 sys.meta_path用来保存一列需要在查询sys.path之前访问的实例
15 模块内建函数:
15.1 __import__(): python1.5加入这个函数, 是实际上的导入模块函数. __import__()函数的语法是: __import__(module_name[, globals[, locals[, fromlist]]])其中module_name是要导入的模块的名称, globals是包含当前全局符号表的名字的字典, locals是包含局部符号表的名字的字典, fromlist是一个使用from-import语句所导入符号的列表…….globals, locals和fromlist默认是globals(), locals(), []
15.2 globals()和locals(), 返回调用者的全局和局部名称空间的字典.
15.3 在全局空间下使用locals()和使用globals()得到的结果是一样的, 因为此时的局部名称空间就是全局名称空间.
15.4 reload(module_name)内建函数可以重新导入一个已经导入的模块(重新加载运行一次该模块)使用reload()重新加载的模块必须是之前被全部导入的模块, 而不能是from-import导入的模块, 也就是说在全局名称空间中必须要有这个模块
页: [1]
查看完整版本: python核心编程--笔记 (转)