文章目錄
- 7.1.1 舊的字串格式化
- 7.2.1 檔案對象的方法
- 7.2.2 pickle模組
有幾種方式來呈現程式的輸出,資料可以以人類可讀的形式列印,或者寫到檔案裡面將來使用。本章我們將討論這些可能性。
7.1 輸出格式
到目前為止,我們遇到了兩種方式來寫值,運算式語句和print()函數。(第三種方式是用檔案對象的write()方法,標準的輸出檔案可以被引用為sys.stdout)
通常你希望對輸出格式有更多的控制而不是簡單的以空格分隔進行列印。有兩種方式來格式化輸出;第一種方式是所有的字串處理都自己做;使用字串的切片和連結操作可以建立出你想象的任何布局。字串類型有一些方法可以執行有用的操作把字串填充到指定的列寬。第二種方式是使用str.format()方法。
string模組包含一個模板類提供另一種方式把值替換到字串裡面。
當然,還有一個問題,怎樣把值轉化為字串,幸運的,Python有方式可以把任何值轉化為字串,把這個值傳遞到repr()或者str()函數。
str()函數的目的是以人類可讀的形式傳回值的表示形式。repr()函數的目的是產生一個解譯器可讀的表示形式(或者將強制產生一個語法錯誤如果沒有相等的文法)。對於那些對人類沒有特別表示形式的對象,str()將返回repr()的值。許多值,像數字或列表和字典結構,對於任何一個函數返回同樣的表示。字串,特殊情況下,有兩個不同的表示。一些樣本:
下面是兩種方式來寫一個平方和立方的表:
注意在第一個樣本裡,每一列直接都加入了一個空格,通過print()的工作方式,它總是在它的參數之間加入空格。
這個樣本示範了字串對象的str.rjust()方法,它把欄位靠右對齊並通過在左邊填充空格達到指定的寬度。有些相似的方法str.ljust()和str.center()。這些方法不寫任何東西,它們僅僅返回一個新的字串。如果輸入字串太長,並不截斷字串,直接返回它,這樣會攪亂你的列布局,但是通常比其他的方法更好。其它情況值可能被截斷了。(如果你真想截斷的話,可以加一個切片操作符,x.ljust(n)[:n])
有另外一個方法,str.zfill(),它在字串的左邊添加零,它能夠理解加號或減號:
str.format()方法的基本使用像這樣:
花括弧和它裡面的字元(叫做格式欄位)被傳入str.format()方法裡面的對象替換,花括弧裡面的數字可以用來引用傳入str.format()方法裡面的對象的位置:
如果str.format()方法裡面使用了關鍵字參數,可以使用這些參數的名字來引用它們的值:
位置參數和關鍵字參數可以被任意結合:
!a(應用ascii())!s(應用str())!r(應用repr())可以用來在格式化前轉換值:
一個可選的:和格式化指示符可以跟在欄位名字的後面,這允許在如何格式化值上面有更大的控制。下面的樣本圓周率Pi保留三位小數:
在:後面傳一個整數使那個欄位具有最小整數的字元寬度。這可以使表格變得漂亮:
如果你有一個很長的格式化字串並且你不想把它分開,較好的方法是使用名字而不是位置來引用被格式化的變數。這可以簡單的通過傳一個字典和使用方括弧訪問索引值來實現:
這也可以使用**把字典當作關鍵字參數來實現:
這是特別有用的,當結合內建函數vars(),它返回一個包含所有本地變數的字典。
7.1.1 舊的字串格式化
%操作符也可以用來進行字串格式化。它解釋左邊的參數(必須像一個sprintf()樣式的格式字串)被應用於右邊的參數,從這個格式化操作返回字串結果。例如:
因為str.format()非常新,許多Python代碼仍然使用%操作符,然而,舊的格式化樣式最終將從語言中刪除,str.format()應該被廣泛使用。
7.2 讀寫檔案
open()返回一個檔案對象,通常使用兩個參數,open(filename, mode):
第一個參數是一個字串包含檔案名稱字,第二個參數是另一個字串包含幾個字元描述檔案將被使用的方式。方式可以是r當檔案被唯讀時,w是唯寫(已經存在的同名檔案將被擦除),a是開啟檔案進行追加,任何寫入檔案的資料自動的加到最後面。r+開啟檔案可以讀寫,方式參數是可選的,如果忽略的話就假定是r。
通常,檔案以文字模式開啟,這意味著,從檔案裡讀出和寫入字串,被一個指定的編碼進行編碼(預設是UTF-8)。b追加到方式後面以二進位的模式開啟檔案,資料的讀出和寫入都以位元組對象的形式。這種模式用於所有的不包含文本的檔案。
在文字模式,預設的是,在讀的時候把平台特定的行結束(Unix是\n,Windows是\r\n)符轉換為\n,在寫的時候把\n轉換為平台特定的行結束符。這種幕後的檔案資料修改對於文字檔是沒問題的,但是將會破壞位元據像JPEG或EXE檔案。當讀寫這樣的檔案時要慎用二進位模式。
7.2.1 檔案對象的方法
這個部分接下類的樣本,將假定有一個叫f的檔案對象已經被建立。
讀一個檔案的內容,調用f.read(size),它讀一定數量的資料,並以字串或位元組對象的形式返回。size是一個可選的數字參數。當size被忽略或是負數時,整個檔案的內容會被讀出並返回。如果檔案的大小是你機器記憶體的兩倍,那就是你的問題。否則,最多的位元組被讀出並返回。如果達到了檔案的末尾,f.read()將返回一個Null 字元串:
f.readline()從檔案中讀出一行,換行字元\n被留在了字串的末尾,只有在檔案的最後一行時會被忽略,前提是檔案不是以一個新行結束。這使得傳回值非常清晰明白,如果f.readline()返回一個Null 字元串,表明檔案的末尾已經達到,同時,一個空白行被表示為一個\n,只包含一個分行符號的字串:
f.readlines()返回一個列表,包含檔案裡面所有的資料行。如果給定一個可選的參數sizehint,從檔案裡讀取很多的位元組,足夠多的來完成一行,並且返回這些行。這通常允許有效以行的形式來讀取一個大檔案,而不用把整個檔案載入到記憶體裡。只有完成的行會被返回:
一個可選的方式來讀取行是迴圈一個檔案對象。這樣可以是記憶體有效,快速,並且代碼更簡單:
這個可選的方式比較簡單,但是不提供細粒度的控制。因為兩種方式管理行的緩衝不同,它們不能被混合在一起。
f.write(string)把字串的內容寫入檔案,返回寫入字元的數目:
要寫入一些不是字串的東西,需要先轉化為字串:
f.tell()返回一個整數給出檔案對象在檔案中的位置,從檔案的開頭以位元組數目來衡量。要改變檔案對象的位置,使用f.seek(offset, from_what)。這個位置是在一個參考點加上位移量算出來的,參考點是用from_what參數來選擇的。0表示從檔案開頭,1表示當前位置,2表示檔案的末尾作為參考點。它可以被忽略,預設是0,表示使用檔案的開頭作為參考點:
在文字檔裡(在開啟模式字串裡面沒有b),只有相對於檔案開頭的尋找被允許(例外情況是可以使用seek(0, 2)尋找檔案的末尾)。
當你用完一個檔案時,調用f.close()來關閉它,並釋放因開啟檔案而佔用的任何系統資源。在調用f.close()後,嘗試再使用檔案對象將自動的失敗:
在處理檔案對象時使用with關鍵字是一個很好的實踐。它的好處是在檔案使用完後會被合適的關閉,即使在使用過程中有異常發生。它比寫相等的try-finally塊要短的多:
檔案對象有一些其它的方法,像isatty()和truncate()使用頻率比較少,查閱參考庫獲得完整的檔案對象指南。
7.2.2 pickle模組
字串可以容易地寫入到檔案和從檔案裡讀出。數字就要稍微花費一些努力,因為read()方法只返回字串,將不得不被傳遞給像int()這樣的函數,它接受一個字串像123並且返回它的數字值123。然而,當你想要儲存比較複雜的資料類型像列表,字典或類的執行個體時,事情會變得更加複雜。
為了不讓使用者經常的寫和調試代碼來儲存複雜的資料類型,Python提供了一個標準的模組叫做pickle。這是一個令人難以置信的模組,可以採用幾乎任何Python對象(甚至一些Python代碼的形式),並把它轉換為一個字串表示;這個過程被叫做pickling。從字串表示重新構造對象被叫做unpickling。在pickling和unpickling之間,對象的字串表示或許已經被存入一個檔案或資料,或通過網路發送到一些遠程機器。
如果你有一個對象x,和一個檔案對象f已經被開啟用於寫入,最簡單的來pickle對象只要一行代碼:
為了再次的unpickle對象,如果f是一個檔案對象已經被開啟用於讀出:
pickle是一個標準的方式使Python對象被其它程式來進行儲存或重新使用,或者被相同的程式在將來進行調用;對於它的技術術語是一個持久化對象。因為pickle是如此的被廣泛使用,許多寫Python擴充的作者都非常小心來確保新的資料類型像矩陣可以被合適的pickle和unpickle。
本文是對官方網站內容的翻譯,原文地址:http://docs.python.org/3/tutorial/inputoutput.html