6. 輸入輸出
6.1 設計輸出格式
輸出值的方法:表達式語句、print語句和write()方法。
想要對輸入字符串格式做一些復雜的控制,有兩種方法。第一,控制整個字符串,使用字符切割和聯接操作創建任意輸出形式。第二,使用%操作符和字符串作為左參數。%操作符將左參數解釋為類似于sprintf()風格的格式字符串,并作用于右參數,從操作中返回格式化的字符串。
Python中可以使用repr()或str()函數,將值轉為字符串。反引號('')等價于repr()。這些函數在未來的Python版本中將會被去掉。
函數str()用于將值轉化為適于人閱讀的形式,而repr()轉化為共解釋器讀取的形式(如果沒有等價的語法,則會發生SyntaxError異常)。某對象沒有適于人閱讀的解釋形式時,str()會返回與repr()等同的值。數值、鏈表、字典對各函數有統一的解讀方式。字符串和浮點數,有獨特的解讀方式。
示例:
>>> s= 'Hello World!'
>>> str(s)
'Hello World!'
>>> repr(s)
"'Hello World!'"
>>> str(0.1)
'0.1'
>>> repr(0.1)
'0.10000000000000001'
>>> hello = 'hello world\n'
>>> print hello
hello world
>>> print repr(hello)
'hello world\n'
>>> print str(hello)
hello world
>>> x = 10*3.25
>>> y = 200*200
>>> 'x, y, (`spam`,`eggs`)'
'x, y, (`spam`,`eggs`)'
>>>
一個輸出平方和立方的例子:
>>> for x in range(1, 11):
... print repr(x).rjust(2), repr(x*x).rjust(3),
... print repr(x*x*x).rjust(4)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
>>>
print方法總會在兩個參數之間增加一個空格。rjust()函數參數為輸出所占的位數,輸出方式為右對齊。類似的函數有ljust()和center()。這些函數只是輸出新的字符串,并不改變它們,如果輸出的字符串太長,也不會被截斷,而是原樣輸出。如果要截斷字符串,可以使用切割操作,如,x.ljust(n)[:n]。
zfill()用于向數值的字符串表達左側填充0。該函數可以正確理解正負號。
>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'
>>>
%操作符使用方法
>>> import math
>>> print 'The value of PI is approximately %5.3f.' % math.pi
The value of PI is approximately 3.142.
>>>
如果有超過一個的字符串要格式化為一體,就需要將它們傳入一個元組做為右值:
>>> table = {'A':001, 'B':002, 'C':003}
>>> for name, phone in table.items():
... print '%-10s ==> %10d' % (name, phone)
...
A ==> 1
C ==> 3
B ==> 2
>>>
大多數類C的格式化操作都需要傳入適當的類型。使用%s格式會更輕松一些:如果對應的參數不是字符串,它會通過內置的str()函數轉化為字符串。Python支持用*作為一個隔離參數來傳遞寬度或精度。Python不支持C的%n和%p操作符。
變量格式化通過名字而不是位置,這樣可以產生符合真實長度的格式化字符串,而不用分隔。這一效果可以通過使用form % (name) format結構來實現:
>>> table = {'A':001, 'B':002, 'C':003}
>>> print 'A:%(A)d; B:%(B)d; C:%(C)d' % table
A:1; B:2; C:3
>>>
這個技巧在新的內置函數vars()組合使用時非常有用,該函數返回一個包含所有局部變量的字典。
6.2 讀寫文件
open()返回一個文件,通過的用法需要兩個參數:open(filename, mode)
>>> f = open('C:/Users/cym/Desktop/1.txt', 'w')
>>> print f
<open file 'C:/Users/cym/Desktop/1.txt', mode 'w' at 0x03D07548>
>>>
mode有:
r,此選項使文件只讀,默認模式;
w,此選項使文件只寫,對于已經存在的同名文件,該操作覆蓋源文件;
a,此選項以追加方式打開文件;
r+,此選項以讀寫方式打開文件。
在Windows和Moc平臺,b模式以二進制方式打開文件,所以會有rb,wb,r+b等等組合。Windows平臺上文本文件與二進制文件是有區別的,讀寫文本文件時,行尾會自動添加行結束符。這種后臺操作方式對ASCII文本文件沒有什么問題,但是操作JPEG或EXE這樣的二進制文件就會產生破壞。在操作這些文件時一定要記得以二進制模式打開。
6.2.1 文件對象方法
讀文件,f.read(size)。該方法讀取若干數量的數據并以字符串形式返回其內容,字符串長度為數值size所指定的大小。如果沒有指定size或者指定為負數,就會讀取并返回整個文件。當文件大小為當前機器內存兩倍時,就會產生問題。正常情況下,會盡可能按比較大的size讀取和返回數據。如果到了文件末尾,f.read()會返回一個空字符串。
>>> f = open('C:/Users/cym/Desktop/1.txt', 'r')
>>> f.read()
''
>>>
f.readline()從文件中讀取單獨一行,字符串結尾會自動加上一個換行符,只有當文件最后一行沒有以換行符結尾時,這一操作才會被忽略。如果f.readline()返回一個空字符串,那就表示到達了文件末尾,如果是一個空行,就會描述為\n,一個只包含換行符的字符串。
f.readlines([size])返回一個列表,包含了文件中所有的數據行。如果給定了size參數,就會讀入多于一行的比特數,從中返回多行文本。這個功能通常用于高效讀取大型行文本,避免了將整個文件讀入內存。這種操作只返回完整的行。
一種另外的方法是循環讀取文件。這是一種內存效率高,速度快,代碼簡單的方法:
>>> for line in f:
... print line,
...
交換通道很簡單,但是不提供完整的控制。因為兩個通道管理線緩沖不同,它們不能混合。
如果需要寫入字符串以外的數據,就要先把這些數據轉換為字符串。
>>> f = open('C:\\Users\\cym\\Desktop\\test.txt','r+')
>>> value = ('the answer', 42)
>>> s = str(value)
>>> f.write(s)
>>> f.close()
>>>
f.tell()返回一個整數,代表文件對象在文件中的指針位置,該數值計量了自文件開頭到指針處的比特數。需要改變文件對象指針的話,使用f.seek(offset, from_what)。指針在該操作中從指定的引用位置移動offset比特,引用位置由from_what參數指定。from_what值為0表示自文件起處開始,1表示自當前文件指針位置開始,2表示自文件末尾開始。from_what可以忽略,其默認值為0,此時從文件頭開始。
文件使用完后,調用f.close()可以關閉文件,釋放打開文件后占用的系統資源。調用f.close()之后,再調用文件對象會自動引發錯誤。
文件對象還有一些不太常用的附加方法,比如isatty()和truncate()。
6.2.2 pickle模塊
我們可以很容易的讀寫文件中的字符串。數值就要多費點周折,因為read()方法只會返回字符串,應該將其傳入int()方法中,就可以將'123'這樣的字符串轉為對應的數值123。不過,當你需要保存更為復雜的數據類型,例如鏈表、字典,類的實例,事情就會變的更復雜了。Python提供了一個名為pickle的標準模塊。這是一個令人贊嘆的模塊,幾乎可以把任何Python對象表達為字符串,這一過程稱之為封裝。從字符串表達出重新構造對象之為拆封unpickling。封裝狀態中的對象可以存儲在文件或對象中,也以通過網絡在遠程的機器之間傳輸。
如果你有一個對象x,一個以寫模式打開的文件對象f,封裝對象的最簡單的方法只需要一行代碼:
pickle.dump(x,f)
如果f是一個以讀模式打開的文件對象,就可以重裝拆封這個對象:
x=pickle.load(f)
pickle是存儲Python對象以供其它程序或其本身以后調用的標準方法。提供這一組技術的一個持久化對象。因為pickle的用途很廣泛,很多Python擴展的作者都非常注意類似矩陣這樣的新數據類型是否適合封裝和拆封。