Python語法速查: 12. 文件與輸入輸出

返回目錄html

 

 (1)文件基本操做

● 文件經常使用操做python

內置函數或方法 描述
open(name [,mode [,buffering]]) 內置函數。用來打開文件,返回一個文件對象(file對象)。詳見下述
f.close() file對象方法,關閉文件。
f.read() file對象方法,讀取最多n個字節,若不指定n,則默認讀取整個文件。讀出的內容以字符串形式返回。
f.readline(size=-1) file對象方法。讀取整行並返回一個字符串,若指定size,則本行最多讀取size個字節。讀出整行時返回字符串中含換行符。
f.readlines(hint=-1) file對象方法。讀取全部行並返回一個列表,每行的字符串爲一個列表元素,hint爲最多讀取的行數。(因爲如今能夠直接對文件對象進行迭代,故readlines()這個方法如今不怎麼用了,詳見下面文件迭代器說明。)
f.write(s) file對象方法。將給定字符串s寫入文件。(若要換行,須要本身在s中加Python換行符)
f.writelines(lines) file對象方法。寫入序列lines中的全部字符串。(換行同上)
f.tell() file對象方法。返回本文件對象在文件中的當前位置指針,返回值爲整數。
f.seek(offset [,whence]) file對象方法。查找文件位置,詳見下述
f.truncate(size=None) file對象方法。將文件截短爲最多size字節。
f.flush() file對象方法。將輸出緩衝區的內容強制寫入磁盤並清空輸出緩衝區。
f.fileno() file對象方法。返回一個整數文件描述符。
f.isatty() file對象方法。判斷file對象是否爲一個交互式終端,返回布爾值。

 

● file對象經常使用屬性安全

屬性 說明
closed 布爾值,表示文件是否已關閉。
mode 字符串,文件的打開模式。詳見下面open()函數的mode參數說明。
name 字符串,文件名
newlines 表示在文件中實際遇到的換行符表示,若還沒遇到換行符,則爲None。
encoding 字符串,表示文件編碼。詳見下面open()函數的encoding參數說明。

 

 

 

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

說明:函數

參數name:含完整路徑的文件名ui

參數mode:見下表中的各個字符,可組合使用,如'rb'或'rw'等。編碼

參數buffering:默認爲-1,即緩衝區大小爲本系統的磁盤塊大小(常爲4096字節),也可用其餘大於1的數字指定緩衝區大小(字節數)。spa

參數encoding:文件的編碼名稱,如:'utf-8'、'ascii'、'cp936'等。操作系統

參數newline:控制通用換行符模式的行爲,可設置爲:'\n', '\r', '\r\n', '', None等。 若是設置爲None,全部形式的換行符(如:'\n', '\r', '\r\n')都會被轉換爲'\n'。 若是設置爲''(空字符串),則全部形式的換行都會被識別爲換行符,但輸入文本不會轉換;指針

參數closefd:布爾值,控制在調用close()方法時,是否實際關閉底層的文件描述符,通常默認爲True。code

字符 含義
r 讀模式(默認)
w 寫模式(首先會把文件現有內容所有清除,而後從頭開始寫)
x 若文件已存在,使用x模式會報錯
a 追加寫模式(從文件現有內容結尾處開始寫)
b 二進制模式
t 文本模式(默認)
+ 讀/寫模式,能夠跟'r'或'w'組合使用。'r+'表示可讀寫(但不清除現有內容);'w+'表示可讀寫(先清除全部內容)
 

關於「文本模式」和「二進制模式」的說明:

在Python3中,在文本模式下打開文件,讀取操做將返回Unicode字符串;若是在二進制模式下打開文件,將返回字節字符串。

若是文件自己是二進制數據文件,因爲read()方法的返回內容格式爲字符串,故「文本模式」和「二進制模式」讀取的內容看上去都像亂碼,須要進一步的處理。

對於文本文件,用「文本模式」和「二進制模式」的效果差很少,惟一的不一樣是在「文本模式」下,Python會自動對文件中的換行符做一些轉換。 在讀取Windows格式的文本文件時,會將Windows形式的換行符'\r\n'轉換成Python標準形式的換行符'\n'。 一樣的,在寫入Windows文本文件時,會將Python的換行符'\n'轉換成Windows形式的'\r\n'寫入文件。 在Linux平臺不做任何轉換。

 

返回索引

 

 

● seek(offset [,whence])

說明:

根據給定的offset和whence中的偏移規則,將本文件對象的當前位置指針移動到任意位置。offset爲一個整數,whence代表offset的偏移起始位置,見下表: (若使用宏名稱,須要import os模塊

宏名稱 整數值 說明
os.SEEK_SET 0 offset從文件頭開始偏移。
os.SEEK_CUR 1 offset爲從當前位置開始偏移。
os.SEEK_END 2 offset爲從文件末尾開始偏移,此時offset一般爲負數。
 

 

返回索引

 

 

● 確保文件被正常關閉的方法

方法一:使用 try / finally

f = open(filename)   # 打開文件
try:
    # …… 文件操做
finally:
    f.close()

 

方法二:使用 with 上下文管理器

with open(filename) as wf:   # with 打開文件後將其賦值到變量 wf 上
    do_somethin(wf)   
    
# 上面語句塊結束後,文件被自動關閉,即便是異常引發的結束也是如此。

 

 

 

 (2)文件內容讀出與文件迭代器

若是文件不是很大,傳統的文件讀出的操做是像下面這樣子的(不使用文件迭代器)。

將文件內容一次性所有讀出,每次處理一個字符:

f = open(filename)
for c in f.read():
    print(c)
f.close()

將文件全部的行一次性所有讀出,每次處理一行:

f = open(filename)
for line in f.readlines():
    print(line)
f.close()

若文件很大,則能夠每次僅讀取一行:

f = openfile(filename)
while True:
    line = f.readline()
    if not line: break    # 當line返回空值時,表面已讀到文件尾
    print(line)
f.close()

 

而如今,文件對象自己是支持迭代的。也就是說,對於很大的文件,不用一次性所有讀出全部內容,用文件對象迭代器就能夠在每次循環時只讀出文件的一部分。

文件迭代器的用法:

f = open(filename)
for line in f:
    print(line)
f.close()

也可讓Python本身負責關閉文件:

for line in open(filename):
    print(line)

 

 

● 使用fileinput模塊

使用fileinput模塊也能夠對文件進行迭代,fileinput模塊還提供一些其餘方法使可以更方便地對多個文件和多個輸入輸出流操做。

fileinput模塊中的經常使用函數

函數 說明
input(files=None, inplace=False, backup='', mode='r', openhook=None) 新建一個FileInput類的實例,用於對若干文件進行操做。files參數爲文件名或輸入流列表,若缺省則默認爲sys.argv[1:]。若inplace參數爲True,文件將原地處理,即:將文件內容複製到backup指定的文件,並將標準輸出流重定向到本文件。
filename() 返回當前文件的名稱。
fileno() 返回當前打開文件的文件描述符(整數),若未打開文件,則返回-1。
lineno() 返回當前累計的行數。即若處理多個文件,行數會累計。
filelineno() 返回當前文件當前行行號。
isfirstline() 剛纔讀入的行是否爲文件的第一行。
isstdin() 最後讀入的一行是否來自sys.stdin
nextfile() 關閉當前文件,移動到下一個文件。
close() 關閉序列。

 

用fileinput對文件進行迭代:

import fileinput
for line in fileinput.input(filename):
    print(line)

 

對目標文件的每行後面添加行號註釋:

# test.py
import fileinput

for line in fileinput.input(inplace=True):    # files參數爲空,默認使用sys.argv[1:]做爲輸入流列表
    line = line.rstrip()
    num = fileinput.lineno()
    print('%-40s # %2i' %(line, num))
    
# 運行:python test.py a.txt 後,會在a.txt文件的每一行後添加註釋行號

 

 

 

 (3)輸入與輸出

Python解釋器提供了3種標準文件對象:標準輸入、標準輸出、標準錯誤,分別在sys模塊中表示爲:sys.stdin, sys.stdout, sys.stderr。 一般,stdin被映射到接受用戶鍵盤輸入信息,而stdout和stderr在屏幕上生成文本。在某些狀況下,集成開發環境(IDE)可能會更改sys.stdin, sys.stdout和sys.stderr。

文件的read()和write()也能夠用於輸出流和輸入流,效果與print()和input()內置函數相同。

import sys
sys.stdout.write('Hello')     # 至關於:print('Hello')
a = sys.stdin.readline()      # 至關於:a = input() ,使用stdin在a中會有一個換行符。

Linux中的管道符號(|),將前一個命令的「標準輸入」和後一個命令的「標準輸出」連在一塊兒,若是你的程序要讀取管道中來的數據,只需使用讀標準輸入便可,如:

import sys
tx = sys.stdin.read()

 

● print()函數

print()函數可接收若干個要在屏幕上打印的參數,入參中間用逗號隔開,在屏幕上各個顯示的入參之間以空格分隔。 若要將print()的內容重定向到一個文件,可使用file=outfile關鍵字參數。若要更改默認的空格分隔,可以使用sep=sepchar關鍵字參數。

print('Hello', 1, 2, 3)   # 輸出顯示爲:Hello 1 2 3
print('Hello', 1, 2, 3, sep=',')    # 輸出顯示爲:Hello,1,2,3
print('Hello', 1, 2, 3, file=f)     # 輸出內容重定向到文件對象f

若要在輸出文本中大量插入變量,可以使用format()方法或string.Template方法,關於它們的用法 詳見這裏

 

 

 

 (4)pickle與shelve模塊

 

● pickle模塊

pickle模塊將對象序列化爲一個字節流,這個字節流能夠寫入到文件並在之後從文件讀出還原成對象。出於安全考慮,程序不該該處理來自不可信來源的文件來還原成對象。

序列化用戶定義類的實例時,只會序列化數據,不會保存相應的類定義,序列化後的數據只包含相關類和模塊的「名稱」。且在還原一個實例時,不會調用其類方法__init__()。

pickle模塊比較適合用於序列化:數字、字符串、元組、列表、只包含可序列化對象的字典、在模塊頂層定義的用戶定義類的實例。

pickle經常使用方法

函數 說明
pickle.dump(obj, file, protocol=None) 將obj序列化並存儲到「文件對象」file中。protocol可爲:0、一、二、三、pickle.HIGHEST_PROTOCOL(自動選擇最新協議)。若obj不支持序列號,則引起pickle.PicklingError異常
pickle.dumps(>obj, protocol=None) 與上面的dump()功能相同,只是不將序列化後的對象寫入文件,而是將其做爲一個bytes對象返回。
pickle.load(file) 從「文件對象」file中加載並還原一個序列化對象。若是該文件沒法還原,則引起pickle.UnpicklingError異常;若是檢測到文件尾,則引起EOFError異常。
pickle.loads(bytes_obj) 與上面load()功能相同,但不是從文件對象還原對象,而是從入參的bytes對象還原。

 

序列化對象和還原序列化示例:

# 序列化寫入文件:
obj1 = SomeObject()
obj2 = SomeObject()
f = open(filename, 'wb')
pickle.dump(obj1, f)      # 先寫入obj1
pickle.dump(obj2, f)      # 再寫入obj2
f.close()

# 還原序列化對象:
f = open(filename, 'rb')
o1 = pickle.load(f)
o2 = pickle.load(f)
f.close()

 

 

● shelve模塊

shelve模塊是基於pickle模塊創建的,但比pickle模塊更加自動化。模塊中的open()函數會建立一個Shelve對象,能夠當作一個普通字典來使用(鍵名必須是字符串),在調用其sync()或close()方法後,其內容將被自動寫入文件。

shelve使用示例:

import shelve
# 保存到文件:
s = shelve.open('test')    # shelve模塊會自動添加擴展名.dat
s['a'] = [1,2,3]
s.close()                  # 保存內容到文件

# 從文件中讀出:
s = shelve.open('test')
print(s['a'])
s['b'] = 'abc'             # 追加內容
del s['a']                 # 刪除鍵'a'及其內容
s.sync()                   # 強制保存內容到文件
s.close()                  # close()會自動調用sync()方法而實現保存做用。

 

 

 

 (5)shutil模塊

shutil模塊用於執行高級的普通文件操做,例如:複製、移動、重命名等,但並不能處理管道、塊設備等特殊文件。

函數 說明
shutil.copy(src, dst) 將文件src複製到文件或目錄下(若dst爲目錄,則複製到目錄下;若dst爲一文件名,則複製到dst同級目錄下並重命名爲指定文件名)。返回新複製的文件名(含路徑)
shutil.copy2(src, dst) 與上面的copy()相似,但同時複製了最後訪問時間和修改時間。
shutil.copytree(src, dst, symlinks=False, ignore=None) 遞歸地複製src下的整個目錄樹,建立目標目錄dst(且不該該已存在),並使用copy2()複製每一個文件。若是symlinks爲True,則對於源目錄樹中的連接文件僅做爲連接文件複製,不然複製真實文件到新目錄樹。 若是在複製過程當中發生錯誤,則將收集錯誤,處理結束時提示Error異常,異常的參數是一份包含了全部錯誤的元組列表 (srcname, dstname, exception)。
shutil.move(src, dst) 將文件或目錄從src移動到dst。若是src移動到了不一樣的文件系統中,將遞歸地複製src。
shutil.rmtree(path, ignore_errors=False, onerror=None) 刪除整個目錄樹。若是ignore_errors爲真,錯誤將被忽略;不然錯誤由onerror函數處理。
shutil.copymode(src, dst) 將文件的模式權限位(如:777)從src複製到dst
shutil.copystat(src, dst) 將權限位、最後訪問時間、最後修改時間從src複製到dst。文件內容、擁有人等保持不變。
shutil.copyfile(src, dst) 將src的內容所有讀出後,複製到dst。
shutil.copyfileobj(f1, f2 [,length]) 將打開的文件對象f1中的全部內容複製到打開的文件對象f2,length可指定最大緩衝容量,若位負數,則一次操做中複製所有數據。
shutil.ignore_pattern(*patterns) 建立一個函數,忽略全部patterns中給出的通配符樣式模式。返回函數的主要用途是做爲shutil.copytree()函數的ignore參數,也可給os.walk()函數使用。

 

 

 

 (6)os模塊中的經常使用文件操做

● os模塊

函數/屬性 說明
sep 屬性。操做系統用於分隔路徑各個部分的字符,在Linux上爲'/',在Windows上爲'\',在Mac上爲':'
getcwd() 返回當前進程的工做路徑字符串。
chdir(path) 將當前進程的工做目錄修改成path。
listdir(path) 返回包含目錄路徑中各文件名和子目錄名的列表(不包括'.'和'..'),不遞歸搜索。
mkdir(path [,mode]) 建立模式爲mode的目錄,默認模式爲777。
makedirs(path [,mode]) 在建立目錄時,會同時建立包含葉子目錄所須要的中間級目錄,若葉子目錄已存在或者沒法建立,將引起OSError異常。
rmdir(path) 刪除目錄,目錄必須爲空。
removedirs(path) 遞歸地目錄刪除函數,即在path描述鏈上的全部目錄都將被刪除。若其中某個目錄不爲空,則中止繼續向上刪除目錄。
remove(path) 刪除文件,同unlink()函數。
unlink(path) 刪除文件,同remove()函數
rename(src, dst) 將文件或目錄src重命名爲dst
renames(old, new) 它會嘗試建立新路徑所需的中間目錄,重命名完成以後,將使用removedirs()刪除舊名稱的目錄鏈。

 

os.path模塊

os.path模塊以一種可移植的方式操做路徑名稱,可由os模塊導入。

函數 說明
文件與目錄的路徑操做
exists(path) 若是path指定的文件或目錄存在,則返回True。若path是已損壞的符號連接,則返回False。
lexists(path) 功能同上,但只要連接文件存在,即使連接損壞也返回True。
isdir(path) 若是path是目錄則返回True。
isfile(path) 若是path是文件則返回True。
islink(path) 若是path是符號連接則返回True。
ismount(path) 若是path是掛載點則返回True。
文件與目錄的屬性操做
getsize(path) 返回path的大小,以字節爲單位
getatime(path) 返回最後一次訪問path的時間,返回值是從紀元起始點開始的秒數。
getctime(path) 返回建立path的時間(Windows)或最後一次修改path的時間(Linux),返回值是從紀元起始點開始的秒數。
getmtime(path) 返回最後一次修改path的時間,返回值是從紀元起始點開始的秒數。
samefile(path1, path2) 若是path1和path2引用同一個文件或目錄,返回True。
sameopenfile(fp1, fp2) 若是打開的文件對象fp1和fp2引用同一個文件,則返回True。
samestat(stat1, stat2) 若是fstat()、lstat()或stat()飯hi的stat對象stat1和stat2引用同一個文件,則返回True。
如下爲純路徑字符串操做(無論實際目錄或文件是否存在)
dirname(path) 返回path所在目錄的名稱。
basename(path) 返回path的基本名稱(即不含父目錄及以上路徑)。
abspath(path) 返回path的絕對路徑。
isabs(path) 若是path是絕對路徑名稱,則返回True。
normpath(path) 返回標準化路徑名稱。它將摺疊多餘分隔符,在Windows上,它把正斜槓轉換爲反斜槓。
normcase(path) 返回標準化路徑名稱並轉換大小寫,在不區分大小寫的文件系統上,它把路徑全轉爲小寫字母,在Windows上,它把正斜槓轉換爲反斜槓。
join(path1 [,path2 [, ...]]) 將一個或多個路徑組件智能鏈接爲一個路徑名稱,例如:join('home', 'a', 'b')返回爲 '/home/a/b'
split(path) 將path拆分爲 (head, tail) 元組,tail爲路徑基本名稱,head是tail以前的內容。至關於 (dirname(), basename())。
splitdrive(path) 將path拆分爲 (driver, filename) 元組。在Windows上,drive是驅動器名,在Linux上,drive爲空字符串。
splitext(path) 將path拆分爲主文件名和後綴(擴展名),如 splittext('a.txt') 的返回值爲 ('a', '.txt')
realpath(path) 返回path的真實路徑,併除去路徑中的全部符號連接(Linux)
relpath(path [,start]) 返回從當前工做目錄到path的一條相對路徑,能夠提供start參數來指定另外一個起始目錄。
commonpath(list) 返回list中各個元素前綴路徑相同的部分,如:os.path.commonpath(['/usr/lib', '/usr/local/lib']),返回:'/usr'
commonprefix(list) 返回list中各個元素前綴相同的部分,如:os.path.commonpath(['/usr/lib', '/usr/local/lib']),返回:'/usr/l'
expanduser(path) 將path中的用戶主目錄'~'替換成當前用戶主目錄的絕對路徑名稱。
expandvars(path) 將path中的'$name'或'${name}'替換成相應環境變量中的值。
其餘
supports_unicode_filenames 變量,若是文件系統支持Unicode文件名,那麼此變量爲True。(通常Windows爲True,Linux爲False)

 

 

 

 

返回目錄

相關文章
相關標籤/搜索