?? open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
該函數(shù)用于打開 file 并返回相應(yīng)的 I/O 對象「也稱文件對象(file object)笼蛛,詳見 "I/O 對象" 小節(jié)」,如果打開失敗則會(huì)拋出 OSError
茎截。
io.open()
其實(shí)是 open()
函數(shù)的別名别渔,而 os.open
被用于創(chuàng)建文件描述符绎谦。新創(chuàng)建的文件和文件描述符都是不可繼承的(non-inheritable)——文件描述符具有"inheritable"標(biāo)志钉凌,該標(biāo)志指示子進(jìn)程是否可以繼承該文件描述符(可閱讀 Inheritance of File Descriptors 和 os.open
遏考,以了解更多信息)
還可查看文件處理模塊翩腐,以了解更多信息鸟款,例如:fileinput
、io
(聲明 open()
函數(shù)的模塊)茂卦、os
何什、os.path
、tempfile
等龙、shutil
处渣。
更新情況:
-
Changed in version 3.3:
添加 opener 參數(shù)
添加
'x'
模式如果以獨(dú)占創(chuàng)建模式 (
'x'
) 打開的文件已存在霍比,則會(huì)拋出FileExistsError
-
Changed in version 3.4:
file 現(xiàn)在屬于 non-inheritable
從 3.4 版本開始已棄用
'U'
模式,待到 4.0 版本時(shí)將移除該模式暴备。
-
Changed in version 3.5:
如果系統(tǒng)調(diào)用被中斷悠瞬,并且信號(hào)處理器(signal handler)沒有拋出異常,
open()
函數(shù)現(xiàn)在會(huì)再次嘗試系統(tǒng)調(diào)用涯捻,而不是拋出InterruptedError
異常( 其基本原理詳見 PEP 475)添加
'namereplace'
錯(cuò)誤處理方案
-
Changed in version 3.6:
支持接收實(shí)現(xiàn)
os.PathLike
的對象在 Windows 上浅妆,打開控制臺(tái)緩沖區(qū)可能會(huì)返回除
io.FileIO
之外的io.RawIOBase
的子類。
參數(shù)說明
file
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file 用于設(shè)置需要打開的文件障癌,有以下兩種形式:
-
可以是一個(gè)表示文件系統(tǒng)路徑(絕對路徑或相對路徑均可)的對象凌外,即 path-like 對象。該對象可以是文本字符串或 byte 字符串涛浙,也可是實(shí)現(xiàn)了
os.PathLike
協(xié)議的對象康辑。"""./somefile.txt中的內(nèi)容 first line second line """ fin = open(b'somefile.txt') print(fin.read()) print(fin.fileno()) # fileno()會(huì)返回文件描述符 fin.close() """Out: first line second line 3 """
-
還可以是一個(gè)整型文件描述符(integer file descriptor),該描述符代表一個(gè)被打包(wrapped)的文件轿亮,可通過
os.open
創(chuàng)建疮薇。如果給出了文件描述符,那么當(dāng)我們關(guān)閉open()
返回的 I/O 對象時(shí)我注,該文件描述符也將被關(guān)閉按咒,除非將 closefd 設(shè)置為False
。另外但骨,有些文檔中可能會(huì)混用文件描述符和文件句柄励七,需要注意區(qū)分這兩個(gè)概念。"""./somefile.txt中的內(nèi)容 first line second line """ import os # 使用底層IO打開一個(gè)文件奔缠,并返回其文件描述符(integer) fd = os.open('somefile.txt', os.O_RDONLY) print("文件描述符的值是 {0}掠抬,類型是 {1}".format(fd, type(fd))) f = open(fd, 'r') print(f.read()) f.close() # f被關(guān)閉后,對應(yīng)的文件描述符也將被關(guān)閉校哎, # 但文件描述符被關(guān)閉后不能再次被打開 f = open(fd, 'r') """Out: 文件描述符的值是 3两波,類型是 <class 'int'> first line second line Traceback (most recent call last): File "c:/Users/iwhal/Desktop/內(nèi)置函數(shù)/BI_open.py", line 13, in <module> f = open(fd, 'r') OSError: [WinError 6] 句柄無效。 """
如果需要再次打開文件描述,則需將 closefd 參數(shù)設(shè)置為
False
:"""./somefile.txt中的內(nèi)容 first line second line """ import os fd = os.open('somefile.txt', os.O_RDONLY) # 將closefd設(shè)置為False f = open(fd, 'r', closefd=False) f.close() f = open(fd, 'r') print(f.read()) """Out: first line second line """
擴(kuò)展閱讀: 5.18 將文件描述符包裝成文件對象 - Python Cookbook
mode
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
mode 用于設(shè)定文件的打開模式雨女,默認(rèn)值是 'rt'
,有如下可用模式:
Character | Meaning |
---|---|
'r' |
open for reading (default)<br />必須保證文件存在阳准,否則會(huì)拋出異常 |
'w' |
open for writing , truncating the file first <br />如果文件已存在氛堕,則會(huì)清空現(xiàn)有內(nèi)容;如果文件不存在野蝇,則會(huì)創(chuàng)建該文件讼稚。必須保證文件所在目錄存在,否則會(huì)拋出異常 |
'x' |
open for exclusive creation, failing if the file already exists<br />如果文件不存在绕沈,則會(huì)創(chuàng)建該文件锐想,并默認(rèn)以 'wt' 打開;如果文件已存在乍狐,則會(huì)拋出 FileExistsError
|
'a' |
open for writing, appending to the end of the file if it exists<br />在某些 Unix 系統(tǒng)中赠摇,這意味著所有寫入都會(huì)被附加到文件的末尾,并且無視 seek 位置 |
'b' |
binary mode (以字節(jié)形式讀寫數(shù)據(jù)浅蚪,用于不包含文本的所有文件)<br />在讀寫 raw bytes 時(shí)藕帜,需使用 binary 模式,并且不需要指定編碼方式 |
't' |
text mode (default)<br />在文本模式下惜傲,如果未指定 encoding洽故,則依賴平臺(tái)的編碼方式,即調(diào)用locale.getpreferredencoding(False) 來獲取當(dāng)前本地編碼方式盗誊。 |
'+' |
open a disk file for updating (reading and writing) |
'U' |
universal newlines mode (deprecated), Use newline to control universal newlines mode.<br />'U' 模式已被棄用时甚,在未來的 Python 版本中將會(huì)引發(fā)異常。該模式在 Python 3 中無效哈踱。 |
前面四個(gè)( 'r'
荒适、'w'
、'x'
嚣鄙、'a'
)需要和后面三個(gè)( 'b'
吻贿、't'
、'+'
)組合使用哑子。
對于二進(jìn)制(binary)讀寫訪問舅列,'w+b'
會(huì)截?cái)辔募?0 字節(jié),但 'r+b'
不會(huì)截?cái)辔募则眩@兩種模式在流中都以 0 偏移量為起點(diǎn)帐要。
如 io
模塊中概述部分所言,Python 會(huì)區(qū)分 binary I/O 和 text I/O: (即使底層操作系統(tǒng)并不會(huì)區(qū)分這兩者弥奸,Python 仍然會(huì)進(jìn)行區(qū)別)
以 binary 模式(
'b'
)打開文件后:在讀取文件時(shí)榨惠,會(huì)將文件中的內(nèi)容以bytes
對象返回,不會(huì)進(jìn)行任何解碼操作;在寫入文件時(shí)赠橙,會(huì)將bytes
對象直接寫入文件耽装,不會(huì)進(jìn)行任何編碼操作。在使用 binary 模式時(shí)期揪,需保持encoding=None
掉奄。-
以 text 模式(
't'
)打開文件后:在讀取文件時(shí),會(huì)先對讀取到的字節(jié)進(jìn)行解碼凤薛,再以str
對象返回解碼后的內(nèi)容姓建;在寫入文件時(shí),會(huì)先對被寫入的str
對象進(jìn)行編碼缤苫,再將編碼得到的字節(jié)寫入文件速兔。在 text 模式下,如果未指定 encoding活玲,則依賴平臺(tái)的編碼方案涣狗,即調(diào)用locale.getpreferredencoding(False)
來獲取當(dāng)前本地編碼方案。在 Windows 下舒憾,默認(rèn)的編碼方式是 cp936:
>>> import locale >>> locale.getpreferredencoding(False) 'cp936'
注意:Python 不依賴于底層操作系統(tǒng)定義的文本文件的概念屑柔;所有處理都由 Python 本身完成,因此與平臺(tái)無關(guān)珍剑。
示例 - 展示 binary 模式和 text 模式的區(qū)別
with open('a_file.txt', 'r+b') as fin:
# 在binary模式下會(huì)直接向文件寫入字節(jié)
fin.write(b'orca_j35 ' + bytes('鯨', 'utf8'))
fin.seek(0)
# 讀取之前寫入的字節(jié)
print(fin.read())
with open('a_file.txt', 'r+', encoding='utf8') as fin:
# 在text模式下掸宛,會(huì)先對讀取到的字節(jié)進(jìn)行解碼,再以字符串對象返回解碼后的內(nèi)容
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 用于設(shè)置緩沖策略(buffering policy)招拙,可以是以下整數(shù)值:
-
0 to switch buffering off (only allowed in binary mode, raise ValueError in text mode) - 會(huì)立即把內(nèi)容輸出至流文件唧瘾,不會(huì)進(jìn)行緩存
>>> f=open('test.txt', 'w+b') # 此時(shí)test.txt中沒有何內(nèi)容 >>> f.write(b'a') 1 # 此時(shí)test.txt中仍然沒有何內(nèi)容,會(huì)先將輸出至文件對象的數(shù)據(jù)進(jìn)行緩存 # 待文件對象關(guān)閉時(shí)别凤,才會(huì)將緩存的數(shù)據(jù)寫入文件對象 >>> f.close() # 此時(shí)test.txt中出現(xiàn)'a' >>> f=open('test.txt', 'w+b', 0) # 此時(shí)test.txt中沒有何內(nèi)容 >>> f.write(b'a') 1 # 此時(shí)test.txt中出現(xiàn)'a' # buffering=0時(shí)不會(huì)緩存數(shù)據(jù)饰序,會(huì)立即把內(nèi)容輸出到流文件,不用等文件對象關(guān)閉后再寫入 >>> f.close() # buffering=0不能用于text模式,否則會(huì)拋出異常 >>> f=open('test.txt', 'wt', 0) Traceback (most recent call last): File "<pyshell#15>", line 1, in <module> f=open('test.txt', 'wt', 0) ValueError: can't have unbuffered text I/O
-
1 to select line buffering (only usable in text mode) - 每次緩存一行數(shù)據(jù)规哪,行分隔符由 newline 參數(shù)決定求豫。
>>> f=open('test.txt', 'w+t', 1) # 此時(shí)test.txt中沒有何內(nèi)容 >>> f.write('abc') 3 # 此時(shí)test.txt中仍沒有何內(nèi)容 >>> f.write('cde\n') 4 # 此時(shí)test.txt中出現(xiàn)'abccde' >>> f.write('efg\r') 4 # 此時(shí)test.txt中出現(xiàn)'efg' # buffering=1對binary模式無效 >>> f=open('test.txt', 'w+b', 1) # 此時(shí)test.txt中沒有何內(nèi)容 >>> f=open('test.txt', 'w+b', 1) >>> f.write(b'abc\n') 4 >>> f.write(b'def\r') 4 # 此時(shí)test.txt中仍沒有何內(nèi)容 >>> f.close() # 此時(shí)test.txt中出現(xiàn)'abc'和'def'
-
an integer > 1 to indicate the size in bytes of a fixed-size chunk buffer - 將緩沖器設(shè)置為給定的尺寸,當(dāng)緩沖器中數(shù)據(jù)的尺寸大于該長度時(shí)诉稍,便會(huì)向文件對象寫入一次數(shù)據(jù)蝠嘉。似乎只對 binary 模式有效,對 text 模式無效杯巨。
>>> f=open('test.txt', 'w+b', 2) >>> f.write(b'ab') 2 # 此時(shí)test.txt中沒有何內(nèi)容 >>> f.write(b'c') 1 # 此時(shí)test.txt中出現(xiàn) 'ab'蚤告,但沒有'c' >>> f.close() # 此時(shí)test.txt中出現(xiàn) 'ab'和'c'
如果沒有給出 buffering 參數(shù),默認(rèn)緩沖策略的工作方式如下:
-
Binary files are buffered in fixed-size chunks; the size of the buffer is chosen using a heuristic trying to determine the underlying device’s “block size” and falling back on
io.DEFAULT_BUFFER_SIZE
. On many systems, the buffer will typically be 4096 or 8192 bytes long.即服爷,二進(jìn)制文件會(huì)以固定尺寸的緩沖器塊進(jìn)行緩存
“Interactive” text files (files for which
isatty()
returnsTrue
) use line buffering. Other text files use the policy described above for binary files.
encoding
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
encoding 用于設(shè)置字符編碼方案杜恰,在編碼(或解碼)文件內(nèi)容時(shí)便會(huì)使用該編碼方案获诈,該參數(shù)只能用于 text 模式。在 codecs
模塊中列舉了 Python 支持的編碼方案心褐。
當(dāng) encoding=None
時(shí)舔涎,編碼方案取決于當(dāng)前平臺(tái),會(huì)通過 locale.getpreferredencoding(False)
來獲取當(dāng)前本地編碼方案逗爹。在 Windows 下终抽,默認(rèn)的編碼方式是 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 用于設(shè)置錯(cuò)誤處理方案,當(dāng)出現(xiàn)編碼(或解碼)錯(cuò)誤時(shí)桶至,便會(huì)使用此錯(cuò)誤處理方案,該參數(shù)不能用于 binary 模式匾旭,默認(rèn)采用 'strict'
镣屹。
errors 的實(shí)參值可以是 Error Handlers 中列出的標(biāo)準(zhǔn)錯(cuò)誤處理方案;也可以是已在 codecs.register_error()
注冊過的任何錯(cuò)誤處理方案的名稱价涝。
標(biāo)準(zhǔn)錯(cuò)誤處理方案包括:
-
'strict'
to raise aValueError
exception if there is an encoding error. The default value ofNone
has the same effect. -
'ignore'
ignores errors. Note that ignoring encoding errors can lead to data loss. -
'replace'
causes a replacement marker (such as'?'
) to be inserted where there is malformed data. -
'surrogateescape'
will represent any incorrect bytes as code points in the Unicode Private Use Area ranging from U+DC80 to U+DCFF. These private code points will then be turned back into the same bytes when thesurrogateescape
error handler is used when writing data. This is useful for processing files in an unknown encoding. -
'xmlcharrefreplace'
is only supported when writing to a file. Characters not supported by the encoding are replaced with the appropriate XML character reference&#nnn;
. -
'backslashreplace'
replaces malformed data by Python’s backslashed escape sequences. -
'namereplace'
(also only supported when writing) replaces unsupported characters with\N{...}
escape sequences.
還可閱讀 codecs.register
的文檔或是運(yùn)行 'help(codecs.Codec)'
女蜈,來了解各種錯(cuò)誤處理方案。
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'
泥栖,具體工作方式如下:
- 從流中讀取輸入數(shù)據(jù)時(shí):
- 如果
newline=None
簇宽,則會(huì)啟用通用換行符模式。輸入數(shù)據(jù)中的行分隔符可以是'\n'
吧享、'\r'
或'\r\n'
魏割,但在將數(shù)據(jù)返回給調(diào)用者之前,這三種換行符均會(huì)被轉(zhuǎn)換為'\n'
钢颂。 - 如果
newline=''
钞它,同樣會(huì)啟用通用換行符模式,但會(huì)將換行符原樣返回給調(diào)用者殊鞭,不會(huì)對換行符進(jìn)行轉(zhuǎn)換遭垛。 - 如果 newline 是
'\n'
、'\r'
操灿、'\r\n'
三者之一耻卡,則在讀取數(shù)據(jù)時(shí)僅會(huì)將 newline 視作行分隔符,并且會(huì)將換行符原樣返回給調(diào)用者牲尺,不會(huì)對換行符進(jìn)行轉(zhuǎn)換卵酪。
- 如果
- 向流中寫入輸出數(shù)據(jù)時(shí):
-
如果
newline=None
幌蚊,則會(huì)將輸出數(shù)據(jù)中所有的'\n'
字符轉(zhuǎn)換為系統(tǒng)默認(rèn)的行分隔符(即,os.linesep
)溃卡。with open('a_file.txt', 'w+t', newline=None) as fin: fin.write('a_\r') fin.write('b_\n') fin.write('c_\r\n') '''a_file.txt中的內(nèi)容如下: a_? b_?? c_? ?? '''
-
如果 newline 是
''
或'\n'
溢豆,則會(huì)將輸出數(shù)據(jù)中的行分隔符原樣保留。with open('a_file.txt', 'w+t', newline='') as fin: fin.write('a_\r') fin.write('b_\n') fin.write('c_\r\n') '''a_file.txt中的內(nèi)容如下: a_? b_? c_?? '''
-
如果 newline 是
'\r'
或'\r\n'
瘸羡,則會(huì)將輸出數(shù)據(jù)中所有的'\n'
字符裝換為 newline漩仙。with open('a_file.txt', 'w+t', newline='\r') as fin: fin.write('a_\r') fin.write('b_\n') fin.write('c_\r\n') '''a_file.txt中的內(nèi)容如下: a_? b_? c_? ? ''' with open('a_file.txt', 'w+t', newline='\r\n') as fin: fin.write('a_\r') fin.write('b_\n') fin.write('c_\r\n') '''a_file.txt中的內(nèi)容如下: a_? b_?? c_? ?? '''
-
closefd
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
如果 closefd=False
并且 file 的值是文件描述符,當(dāng)我們關(guān)閉 open()
返回的文件對象時(shí)犹赖,底層文件描述符依舊會(huì)保持打開狀態(tài)队他。
如果 closefd=True
并且 file 的值是文件描述符,當(dāng)我們關(guān)閉 open()
返回的文件對象時(shí)峻村,底層文件描述符也將被關(guān)閉麸折。
如果 file 的值是某個(gè)路徑,那么 closefd 必須保持默認(rèn)狀態(tài)(True
)粘昨,否則會(huì)拋出異常垢啼。
opener
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
opener 用于設(shè)置自定義開啟器(opener)。調(diào)用開啟器( 即 opener(file, flags)
)后张肾,可獲得文件對象的底層文件描述符芭析。開啟器的返回值必須是一個(gè)打開的文件描述符。opener=os.open
與 opener=None
的等效吞瞪。
The following example uses the dir_fd parameter of the os.open()
function to open a file relative to a given directory:
在下面這個(gè)示例中馁启,將使用 os.open()
函數(shù)的 dir_fd 參數(shù)來打開相對于給定目錄的文件:
>>> 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()
函數(shù)返回的 I/O 對象的類型取決于 mode 參數(shù):
-
當(dāng)以 text 模式(
'w'
,'r'
,'wt'
,'rt'
, etc.)打開某個(gè)文件時(shí)芍秆,將返回io.TextIOBase
的子類(io.TextIOWrapper
)的實(shí)例with open('a_file.txt', 'r') as fin: print(type(fin)) # Out:<class '_io.TextIOWrapper'> with open('a_file.txt', 'w') as fin: print(type(fin)) # Out:<class '_io.TextIOWrapper'> with open('a_file.txt', 'r+') as fin: print(type(fin)) # Out:<class '_io.TextIOWrapper'>
-
當(dāng)以 binary 模式打開某個(gè)啟用 buffering 的文件時(shí)进统,將返回
io.BufferedIOBase
的子類的實(shí)例,具體的子類如下:- 在 read binary 模式下浪听,將返回
io.BufferedReader
類的實(shí)例 - 在 write(or append) binary 模式下螟碎,將返回
io.BufferedWriter
類的實(shí)例 - 在 read/write binary 模式下,將返回
io.BufferedRandom
類的實(shí)例
# 注意,已啟用buffering,詳見之后的buffering小節(jié) with open('a_file.txt', 'rb') as fin: print(type(fin)) # Out:<class '_io.BufferedReader'> with open('a_file.txt', 'wb') as fin: print(type(fin)) # Out:<class '_io.BufferedWriter'> with open('a_file.txt', 'r+b') as fin: print(type(fin)) # Out:<class '_io.BufferedRandom'>
- 在 read binary 模式下浪听,將返回
-
當(dāng)禁用 buffering 時(shí)迹栓,將返回原始流(raw stream)掉分,即
io.RawIOBase
的子類(io.FileIO
)的實(shí)例# 注意,buffering=0便會(huì)禁用緩沖器,詳見之后的buffering小節(jié) with open('a_file.txt', 'rb', 0) as fin: print(type(fin)) # Out:<class '_io.FileIO'> with open('a_file.txt', 'wb', 0) as fin: print(type(fin)) # Out:<class '_io.FileIO'> with open('a_file.txt', 'r+b', 0) as fin: print(type(fin)) # Out:<class '_io.FileIO'>
io
模塊中,各個(gè) I/O 類間的繼承關(guān)系如下:
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()
酥郭。
關(guān)閉 I/O 對象
現(xiàn)代操作系統(tǒng)不允許普通程序直接操作磁盤,對磁盤內(nèi)文件的讀寫功能愿吹,均由操作系統(tǒng)提供的不从。對文件進(jìn)行讀寫,其實(shí)就是請求操作系統(tǒng)打開一個(gè)文件對象(通常稱為文件描述符)犁跪,然后通過操作系統(tǒng)提供的接口向該對象讀/寫數(shù)據(jù)椿息。
在執(zhí)行寫操作時(shí)歹袁,部分 I/O 對象會(huì)先將數(shù)據(jù)緩存到內(nèi)存中(參考 buffering 小節(jié)),并不會(huì)立刻把數(shù)據(jù)寫入磁盤寝优。只有在關(guān)閉 I/O 對象時(shí)条舔,才會(huì)保證把沒有寫入的數(shù)據(jù)全部寫入磁盤(也被稱作 flush)。因此乏矾,在執(zhí)行寫入操作后孟抗,如果沒有關(guān)閉 I/O 對象,則很有可能會(huì)丟失數(shù)據(jù)钻心。另外凄硼,被打開的 I/O 對象還會(huì)占用系統(tǒng)資源。所有捷沸,在使用完 I/O 對象后摊沉,必須確保其正確關(guān)閉。
關(guān)閉 I/O 對象最直接方式是調(diào)用 close()
方法:
fin = open('a_file.txt', 'r')
"""--snip--:操作IO對象亿胸,最后關(guān)閉IO對象"""
fin.close()
這種方式的缺點(diǎn)是,如果在讀寫 I/O 對象的過程中拋出 IOError
異常预皇,便無法關(guān)閉 I/O 對象侈玄。為了確保 I/O 對象被順利關(guān)閉,可使用如下兩種方法:
-
使用
try...finally
語句try: fin = open('/path/to/file', 'r') """--snip--:操作IO對象吟温,最后關(guān)閉IO對象""" finally: fin.close()
-
使用
with
語句with open("myfile.txt") as f: for line in f: print(line, end="")
關(guān)于 try...finally
和 with
語句序仙,可閱讀筆記『0x11 錯(cuò)誤、調(diào)試和測試.md 』-> 2. 處理異常
StringIO & BytesIO
io.StringIO
會(huì)在內(nèi)存中創(chuàng)建一個(gè) text I/O 流鲁豪;io.BytesIO
會(huì)在內(nèi)存中創(chuàng)建一個(gè) bytes I/O 流潘悼。
詳見筆記『io — Core tools for working with streams.md』
術(shù)語
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 bytes
object 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.