有幾種方式來呈現程序的輸出,數據可以以人類可讀的形式打印,或者寫到文件里面將來使用。本章我們將討論這些可能性。
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()將返回一個空字符串:

f.readline()從文件中讀出一行,換行字符\n被留在了字符串的末尾,只有在文件的最后一行時會被忽略,前提是文件不是以一個新行結束。這使得返回值非常清晰明白,如果f.readline()返回一個空字符串,表明文件的末尾已經達到,同時,一個空白行被表示為一個\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
