程序员

open()

2018-12-03  本文已影响0人  import_hello

转载须注明出处:简书@Orca_J35 | GitHub@orca-j35

🔨 open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

该函数用于打开 file 并返回相应的 I/O 对象「也称文件对象(file object),详见 "I/O 对象" 小节」,如果打开失败则会抛出 OSError

io.open() 其实是 open() 函数的别名,而 os.open 被用于创建文件描述符。新创建的文件和文件描述符都是不可继承的(non-inheritable)——文件描述符具有"inheritable"标志,该标志指示子进程是否可以继承该文件描述符(可阅读 Inheritance of File Descriptorsos.open,以了解更多信息)

还可查看文件处理模块,以了解更多信息,例如:fileinputio (声明 open() 函数的模块)、osos.pathtempfileshutil

更新情况:

参数说明

file

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

file 用于设置需要打开的文件,有以下两种形式:

mode

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

mode 用于设定文件的打开模式,默认值是 'rt',有如下可用模式:

Character Meaning
'r' open for reading (default)<br />必须保证文件存在,否则会抛出异常
'w' open for writing , truncating the file first <br />如果文件已存在,则会清空现有内容;如果文件不存在,则会创建该文件。必须保证文件所在目录存在,否则会抛出异常
'x' open for exclusive creation, failing if the file already exists<br />如果文件不存在,则会创建该文件,并默认以 'wt' 打开;如果文件已存在,则会抛出 FileExistsError
'a' open for writing, appending to the end of the file if it exists<br />在某些 Unix 系统中,这意味着所有写入都会被附加到文件的末尾,并且无视 seek 位置
'b' binary mode (以字节形式读写数据,用于不包含文本的所有文件)<br />在读写 raw bytes 时,需使用 binary 模式,并且不需要指定编码方式
't' text mode (default)<br />在文本模式下,如果未指定 encoding,则依赖平台的编码方式,即调用locale.getpreferredencoding(False) 来获取当前本地编码方式。
'+' open a disk file for updating (reading and writing)
'U' universal newlines mode (deprecated), Use newline to control universal newlines mode.<br />'U' 模式已被弃用,在未来的 Python 版本中将会引发异常。该模式在 Python 3 中无效。

前面四个( 'r''w''x''a' )需要和后面三个( 'b''t''+' )组合使用。

对于二进制(binary)读写访问,'w+b' 会截断文件至 0 字节,但 'r+b' 不会截断文件,这两种模式在流中都以 0 偏移量为起点

io 模块中概述部分所言,Python 会区分 binary I/O 和 text I/O: (即使底层操作系统并不会区分这两者,Python 仍然会进行区别)

注意:Python 不依赖于底层操作系统定义的文本文件的概念;所有处理都由 Python 本身完成,因此与平台无关。

示例 - 展示 binary 模式和 text 模式的区别

with open('a_file.txt', 'r+b') as fin:
    # 在binary模式下会直接向文件写入字节
    fin.write(b'orca_j35 ' + bytes('鲸', 'utf8'))
    fin.seek(0)
    # 读取之前写入的字节
    print(fin.read())

with open('a_file.txt', 'r+', encoding='utf8') as fin:
    # 在text模式下,会先对读取到的字节进行解码,再以字符串对象返回解码后的内容
    print(fin.read())
"""Out:
b'orca_j35 \xe9\xb2\xb8'
orca_j35 鲸
"""

buffering

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

buffering 用于设置缓冲策略(buffering policy),可以是以下整数值:

如果没有给出 buffering 参数,默认缓冲策略的工作方式如下:

encoding

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

encoding 用于设置字符编码方案,在编码(或解码)文件内容时便会使用该编码方案,该参数只能用于 text 模式。在 codecs 模块中列举了 Python 支持的编码方案。

encoding=None 时,编码方案取决于当前平台,会通过 locale.getpreferredencoding(False) 来获取当前本地编码方案。在 Windows 下,默认的编码方式是 cp936:

>>> import locale
>>> locale.getpreferredencoding(False)
'cp936'

errors

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

errors 用于设置错误处理方案,当出现编码(或解码)错误时,便会使用此错误处理方案,该参数不能用于 binary 模式,默认采用 'strict'

errors 的实参值可以是 Error Handlers 中列出的标准错误处理方案;也可以是已在 codecs.register_error() 注册过的任何错误处理方案的名称。

标准错误处理方案包括:

还可阅读 codecs.register 的文档或是运行 'help(codecs.Codec)' ,来了解各种错误处理方案。

with open('a_file.txt', 'w', encoding='utf8') as fin:
    fin.write('逆戟鲸 orca_j35')
with open('a_file.txt', 'r', encoding='utf8') as fin:
    print(fin.read())
with open('a_file.txt', 'r', encoding='ascii', errors='ignore') as fin:
    print(fin.read())
with open('a_file.txt', 'r', encoding='ascii', errors='replace') as fin:
    print(fin.read())
'''Out:
逆戟鲸 orca_j35
 orca_j35
��������� orca_j35
'''

newline

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

newline 用于控制通用换行符模式( 'U' )的工作方式,只能用于 text 模式,其值可以是None'''\n''\r''\r\n',具体工作方式如下:

closefd

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

如果 closefd=False 并且 file 的值是文件描述符,当我们关闭 open() 返回的文件对象时,底层文件描述符依旧会保持打开状态。

如果 closefd=True 并且 file 的值是文件描述符,当我们关闭 open() 返回的文件对象时,底层文件描述符也将被关闭。

如果 file 的值是某个路径,那么 closefd 必须保持默认状态(True),否则会抛出异常。

opener

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

opener 用于设置自定义开启器(opener)。调用开启器( 即 opener(file, flags) )后,可获得文件对象的底层文件描述符。开启器的返回值必须是一个打开的文件描述符。opener=os.openopener=None 的等效。

The following example uses the dir_fd parameter of the os.open() function to open a file relative to a given directory:

在下面这个示例中,将使用 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)  # don't leak a file descriptor

I/O 对象

如需了解以下 I/O 对象包含的属性,请查看笔记『io — Core tools for working with streams.md』

open() 函数返回的 I/O 对象的类型取决于 mode 参数:

io 模块中,各个 I/O 类间的继承关系如下:

IOBase
|--RawIOBase
    |--FileIO
|--BufferedIOBase
    |--BytesIO
    |--BufferedReader
    |--BufferedWriter
    |--BufferedRandom
    |--BufferedRWPair
|--TextIOBase
    |--TextIOWrapper
    |--StringIO

可迭代

以上提到的三种 I/O 对象均是可迭代对象:

from collections import abc
with open('a_file.txt', 'r') as fin:
    assert isinstance(fin, abc.Iterable)
with open('a_file.txt', 'rb') as fin:
    assert isinstance(fin, abc.Iterable)
with open('a_file.txt', 'rb', 0) as fin:
    assert isinstance(fin, abc.Iterable)

因此, for line in file: ... 等效于 for line in file.readlines()

关闭 I/O 对象

现代操作系统不允许普通程序直接操作磁盘,对磁盘内文件的读写功能,均由操作系统提供的。对文件进行读写,其实就是请求操作系统打开一个文件对象(通常称为文件描述符),然后通过操作系统提供的接口向该对象读/写数据。

在执行写操作时,部分 I/O 对象会先将数据缓存到内存中(参考 buffering 小节),并不会立刻把数据写入磁盘。只有在关闭 I/O 对象时,才会保证把没有写入的数据全部写入磁盘(也被称作 flush)。因此,在执行写入操作后,如果没有关闭 I/O 对象,则很有可能会丢失数据。另外,被打开的 I/O 对象还会占用系统资源。所有,在使用完 I/O 对象后,必须确保其正确关闭。

关闭 I/O 对象最直接方式是调用 close() 方法:

fin = open('a_file.txt', 'r')
"""--snip--:操作IO对象,最后关闭IO对象"""
fin.close()

这种方式的缺点是,如果在读写 I/O 对象的过程中抛出 IOError 异常,便无法关闭 I/O 对象。为了确保 I/O 对象被顺利关闭,可使用如下两种方法:

关于 try...finallywith 语句,可阅读笔记『0x11 错误、调试和测试.md 』-> 2. 处理异常

StringIO & BytesIO

io.StringIO 会在内存中创建一个 text I/O 流;io.BytesIO 会在内存中创建一个 bytes I/O 流。
详见笔记『io — Core tools for working with streams.md』

术语

file object

An object exposing a file-oriented API (with methods such as read() or write()) to an underlying resource. Depending on the way it was created, a file object can mediate access to a real on-disk file or to another type of storage or communication device (for example standard input/output, in-memory buffers, sockets, pipes, etc.). File objects are also called file-like objects or streams.

There are actually three categories of file objects: raw binary files, buffered binary filesand text files. Their interfaces are defined in the io module. The canonical way to create a file object is by using the open() function.

file-like object

A synonym for file object.

path-like object

An object representing a file system path. A path-like object is either a str or bytesobject representing a path, or an object implementing the os.PathLike protocol. An object that supports the os.PathLike protocol can be converted to a str or bytes file system path by calling the os.fspath() function; os.fsdecode() and os.fsencode() can be used to guarantee a str or bytes result instead, respectively. Introduced by PEP 519.

text file

A file object able to read and write str objects. Often, a text file actually accesses a byte-oriented datastream and handles the text encoding automatically. Examples of text files are files opened in text mode ('r' or 'w'), sys.stdin, sys.stdout, and instances ofio.StringIO.

See also binary file for a file object able to read and write bytes-like objects.

text encoding

A codec which encodes Unicode strings to bytes.

universal newlines

A manner of interpreting text streams in which all of the following are recognized as ending a line: the Unix end-of-line convention '\n', the Windows convention '\r\n', and the old Macintosh convention '\r'. See PEP 278 and PEP 3116, as well asbytes.splitlines() for an additional use.

上一篇 下一篇

猜你喜欢

热点阅读