21: 文件 I/O
在Python 3中,file不再是内置名称(open仍然有效)。
文件I/O的内部细节已被移至标准库中的io模块,这也是StringIO的新家:
import io
assert io.open is open # the builtin is an alias
buffer = io.StringIO()
buffer.write('hello, ') # returns number of characters written
buffer.write('world!\n')
buffer.getvalue() # 'hello, world!\n'
文件模式(文本与二进制)现在决定了读取文件时产生的数据类型(以及写入时所需的类型):
with open('data.txt') as f:
first_line = next(f)
assert type(first_line) is str
with open('data.bin', 'rb') as f:
first_kb = f.read(1024)
assert type(first_kb) is bytes
文本文件的编码默认为
locale.getpreferredencoding(False)返回的值。要显式指定编码,请使用encoding关键字参数:
with open('old_japanese_poetry.txt', 'shift_jis') as text:
haiku = text.read()
22: Python 3中移除cmp函数
在Python 3中,cmp内置函数以及__cmp__特殊方法被移除。
根据文档:
cmp()函数应视为已不存在,__cmp__()特殊方法不再受支持。
使用__lt__()进行排序,__eq__()与__hash__()一起使用,以及根据需要使用其他富比较方法。(如果你真的需要cmp()的功能,可以使用表达式(a > b) - (a < b)作为cmp(a, b)的等效物。)
此外,所有接受cmp参数的内置函数现在只接受key关键字参数。
在functools模块中,还有一个有用的函数cmp_to_key(func),它允许你将cmp风格的函数转换为key风格的函数:
将旧风格的比较函数转换为键函数。用于接受键函数的工具(例如sorted()、min()、max()、heapq.nlargest()、heapq.nsmallest()、itertools.groupby())。此函数主要用于正在从Python 2转换为Python 3的程序。
23: 八进制常量
在Python 2中,可以这样定义八进制字面量:
>>> 0755 # only Python 2
为了确保跨版本兼容性,请使用:
0o755 # both Python 2 and Python 3
24: 写入文件对象时的返回值
在Python 2中,直接写入文件句柄会返回None:
Python 2.x Version ≥ 2.3
hi = sys.stdout.write('hello world\\n')
# Out: hello world
type(hi)
# Out:
在Python 3中,写入句柄会返回写入的字符数(写入文本时)或写入的字节数(写入字节时):
Python 3.x Version ≥ 3.0
import sys
char_count = sys.stdout.write('hello world ?\\n')
# Out: hello world ?
char_count
# Out: 14
byte_count = sys.stdout.buffer.write(b'hello world \\xf0\\x9f\\x90\\x8d\\n')
# Out: hello world ?
byte_count
# Out: 17
25: Python 3中exec语句是函数
在Python 2中,exec是一个语句,具有特殊的语法:exec code [in globals[, locals]]。在Python 3中,exec现在是一个函数:exec(code, [, globals[, locals]]),Python 2中的语法将引发SyntaxError。
正如print从语句变为函数一样,也添加了一个__future__导入。然而,没有from __future__ import exec_function,因为不需要:Python 2中的exec语句也可以使用与Python 3中exec函数调用完全相同的语法。因此,你可以将语句
Python 2.x Version ≥ 2.3
exec 'code'
exec 'code' in global_vars
exec 'code' in global_vars, local_vars
更改为形式
Python 3.x Version ≥ 3.0
exec('code')
exec('code', global_vars)
exec('code', global_vars, local_vars)
后者的形式保证在Python 2和Python 3中完全相同地工作。