liuliuab1 发表于 2014-12-8 23:00:48

Python 2.7.8 与 Python 3.3.5 的 open() 内置函数的差别

Python 2.7.8 与 Python 3.3.5 的 open() 内置函数的差别
       以前学 Python 也不觉得,因为同大家一样,一开始会选其中一个版本来学,要么是 Python 2,要么是 Python 3,今天把这两个版本的 open() 内置函数仔细研究了一下,发现,真的差别很大,Python 3 下的 open() 内置函数看起来功能真丰富。不多说,摘录一段 “官方英文帮助文件” 中文翻译,同大家一起分享。

以下为 “Python 2.7.8 官方英文帮助文件” 中文翻译部分摘录:

open(name[, mode[, buffering]])
       打开文件,返回 File Objects (文件对象)章节所述的 file (文件) 类型对象。若文件不能被打开,则会引发IOError (输入/输出错误)。打开文件时,使用 open() 函数比直接援引 file (文件)构造函数更可取。

      前 2 自变量与stdio (标准 输入/输出) 的 fopen() 方法类似:name 是要打开的文件名,mode 是如何打开文件的字符串指示。

      mode 常-用值,包括 'r' 读取,'w' 写入 (截取,若文件已存在),'a' 追加 (在某些 Unix 系统,这意味着所有写入会被追加到文件末尾,而不管当前定位位置)。若省略 mode,则默认为 'r'。默认使用文本模式,在写入和返回读取时,会把 '\n' 字符转换成特定-平台表示。因此,当打开二进制文件时,应把 'b' 追加到 mode 值,从而以改善可移植性的二进制模式找开文件。(追加 'b'会很有用,甚至在系统把二进制文件与文本文件视为相同时,它还可充当文档编制。) 见下文,mode 还有更多可能值。

      可选 buffering 自变量可指定文件期望的缓冲区大小:0 意味着不缓冲,1 意味着行缓冲,任何其它正值意味着使用 (以字节为单位的) 相应 ( 近似) 缓冲区大小。负 buffering 意味着使用系统默认;对于 tty (电传打字机) 设备而言,通常是行缓冲,其它文件则为完全缓冲。若省略,则使用系统默认。

      以 'r+'、'w+'、'a+' 模式打开会 (读、写) 更新文件;注意:'w+' 还会截取文件。在有区分二进制文件与文本文件的系统中,把 'b' 追加到 mode 会以二进制模式打开文件;在没有区分二进制文件与文本文件的系统中,添加 'b' 没有任何作用。

      除标准 fopen() 值外,mode 还可为 'U' 或 'rU'。Python 通常以 universal newlines (通用换行符) 支持构建;提供 'U' 会把文件打开为文本文件,但会通过下列任一行-尾约定终止行,譬如:Unix 行-尾约定为 '\n',Macintosh 为 '\r',Windows 为 '\r\n'。Python 程序会把所有这些外部表示视为 '\n'。若 Python 未以通用换行符支持构建,则 mode 为 'U' 会与普通文本模式相同。注意:这样打开的文件对象,还有 None 值 (若没有换行,但仍可见的话)、'\n'、'\r'、'\r\n'newlines (换行符) 属性、或含有所有可见换行类型的元组。

      在剥离 'U' 后,Python 强制施行以 'r'、'w' 或 'a' 模式开头。

      Python 提供了多种文件处理模块,包括 fileinput (文件输入)、os (操作系统)、os.path ( 操作系统.路径 ), tempfile (临时文件) 及 shutil。

改变于 2.5 版:引入 mode 字符串首字母限定。

以下为 “Python 3.3.5 官方英文帮助文件” 中文翻译部分摘录:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
      打开 file 并返回相应 file object (文件对象)。若文件不能被打开的话,会引发 OSError (操作系统错误)。

      file 要么是可给出打开文件路径名 (绝对或相对当前工作目录) 的字符串或字节对象,要么是包裹文件的整数文件描述符。(若给定文件描述符,当关闭返回 I/O 对象时,也会关闭文件描述符,除非 closefd 被设为 False。)

      mode 是能指定文件打开方式的可选字符串。默认值为 'r',意味着以文本模式读取打开。其它常见值,包括:'w' 写入 (截取文件,若文件已存在)、'x' 独占创建、'a' 追加 (在某些 Unix 系统,意味着所有写入会被追加到文件末尾,不管当前定位位置)。在文本模式下,若不指定 encoding,使用编码会从属平台:可调用 locale.getpreferredencoding(False) 函数获取当前区域设置编码。(原生字节会以二进制模式读写,不必指定 encoding。) 可用模式包括:


字符含义
'r'读取打开 (默认)
'w'写入打开 (会先截取文件)
'x'独占创建打开 (若文件已存在的话,操作会失败)
'a'写入打开 (若文件存在的话,会追加到文件末尾)
'b'二进制模式
't'文本模式 (默认)
'+'更新打开磁盘文件 (读写)
'U'通用换行符模式 (为保持向后兼容;不应用于新代码)

       默认模式为 'r' (读取打开文本,同义词 'rt')。二进制读-写访问模式 'w+b':打开文件并截取到 0 字节。'r+b':不截取打开文件。

       如Overview (概述) 所述,Python 会区分二进制 I/O 和文本 I/O。以二进制模式 (mode 自变量含有 'b') 打开文件时,无需任何解码就能返回 bytes (字节) 对象内容。在文本模式 (默认,或当 mode 自变量含有 't' 时) 下,会以 str (字符串) 形式返回文件内容 (会先用从属平台编码或给定 encoding解码字节)。


注意Python 不会依赖底层操作系统文本文件概念;所有处理都由 Python 自身完成,因此,独立于-平台。

       buffering 是用来设置缓冲策略的可选整数。传递 0 会关闭缓冲 (只允许用于二进制模式);传递 1 会选择行缓冲 (只可用于文本模式);传递 > 1 的整数,会以字节为单位指示固定-尺寸组块缓冲区大小。当不给定 buffering 自变量时,默认缓冲策略工作方式如下:


[*]二进制文件会以固定-尺寸组块方式缓冲;会试探性试着确定底层设备 “块尺寸” 选择缓冲区大小,并回落到io.DEFAULT_BUFFER_SIZE。在很多系统,缓冲区通常是 4096 或 8192 字节长。
[*]“交互” 文本文件 (isatty() 方法会返回 True 的文件) 会使用行缓冲。其它文本文件会使用上文所述的二进制文件策略。
[*]
       encoding 是用于解码或编码文件的编码名称。这只应用于文本模式。默认编码从属平台 (不管locale.getpreferredencoding() 函数返回什么);而且,被 Python 支持的任何编码都可以使用。请参阅 codecs (编解码器) 模块,了解支持编码列表。

       errors 是能指定该如何处理编码、解码错误的可选字符串 – 不可用于二进制模式。有多种标准错误处理程序;尽管以 codecs.register_error() 函数注册的任何错误处理名称也是可用的。标准名称,包括:


[*]'strict (严格)':会引发 ValueError (值错误) 异常,若存在编码错误的话。默认值 None 具有相同效果。
[*]'ignore (忽略)':忽略错误。注意:忽略编码错误会导致数据丢失。
[*]'replace (替换)':会导致置换标记 (比如:'?') 被插入在格式错误数据处。
[*]'surrogateescape (代理转义)':会以 U+DC80 到 U+DCFF 的私有使用区域范围间的 Unicode 代码点表示任何不正确字节。在写入数据时,会把那些私有代码点变成相同字节,当使用 surrogateescape (代理转义) 错误处理程序时。这会很有用,当以未知编码处理文件时。
[*]'xmlcharrefreplace (以 XML 字符引用替换)':当写入文件时,才支持。会以适当 XML 字符引用 &#nnn; 替换编码不支持字符。
[*]'backslashreplace (以反斜杠替换)':(也只有写入时,才支持) 以 Python 反斜杠转义序列替换不支持字符。
[*]
       newline 能控制 universal newlines (通用换行符) 模式如何工作 (只适于文本模式)。它可为 None、''、'\n'、'\r'、'\r\n'。工作方式,如下:

[*]当从流读取输入时,若 newline 为 None,则会启用 universal newlines (通用换行符) 模式。输入行会以 '\n'、'\r'、'\r\n' 结束;且在返回给调用者前,这些会被转译成 '\n'。若为 '' 的话,会启用通用换行符模式 (但行尾不会转译返回给调用者)。若为其它任意合法值的话,只会以给定字符串终止输入行 (且行尾不会转译返回给调用者)。
[*]当把输出写入流时,若 newline 为 None 的话,任何写入 '\n' 字符都会被转译成系统默认 os.linesep 行分隔符。若 newline 为 '' 或 '\n' 的话,就不会发生转译。若 newline 为其它任何合法值的话,任何写入 '\n' 字符都会被转译成给定字符串。
[*]
       若 closefd 为 False 且给定的是文件描述符而非文件名,那么,当关闭文件时,底层文件描述符会保持打开。若给定文件名的话,closefd 会不起作用且其必须为 True (默认值)。

       opener 可用来传递自定义可调用opener (开启器)。那么,以 (file, flags) 调用 opener 可获得文件对象底层文件描述符。opener 必须返回打开文件描述符;传递 os.open 作为 opener,在泛函性方面结果类似传递 None。

       以下范例会以 os.open() 函数的 dir_fd 参数,相对给定目录打开文件:

>>> import os
>>> dir_fd = os.open('somedir', os.O_RDONLY)
>>> def opener(path, flags):
...   return os.open(path, flags, dir_fd=dir_fd)
...
>>> with open('spamspam.txt', 'w', opener=opener) as f:
...   print('This will be written to somedir/spamspam.txt', file=f)
...
>>> os.close(dir_fd)# 不要漏了文件描述符

改变于 3.3 版:添加 opener 参数。添加模式 'x'。

       由 open()内置函数返回的 file object (文件对象) 类型从属模式。当 open() 内置函数以 ('w'、'r'、'wt'、'rt'、等等) 文本模式打开文件时,会返回 io.TextIOBase (基本文本 IO) 子类;具体而言,就是io.TextIOWrapper (文本 IO 包裹器)。当以带缓冲的二进制模式打开文件时,会返回 io.BufferedIOBase (基本缓冲 IO) 子类。准确点说:在二进制读取模式下,它会返回 io.BufferedReader (缓冲读取器);在二进制写入、追加模式下,它会返回 io.BufferedWriter (缓冲写入器),但在读/写模式下,它会返回 io.BufferedRandom (随机缓冲)。当禁用缓冲时,会返回原生流、io.RawIOBase (基本原生 IO) 子类、io.FileIO (文件 IO)。

       另请参阅其它文件处理模块,譬如:fileinput (文件输入)、io (输入/输出) (会声明 open() 内置函数)、os (操作系统)、os.path (操作系统.路径)、tempfile (临时文件)、shutil。

改变于 3.3 版:过去引发的 IOError (输入/输出错误) 现在是 OSError (操作系统错误) 的别名。FileExistsError (文件存在错误) 会被引发,若要以独占创建模式 ('x') 打开的文件已存在的话。

版权声明:
本文为独家原创稿件,版权归 德云社区,未经许可不得转载;否则,将追究法律责任。


页: [1]
查看完整版本: Python 2.7.8 与 Python 3.3.5 的 open() 内置函数的差别