程序會有輸入和輸出,輸入可以從標准輸入或是從一個文件讀入數據,程序的輸出可以以一種友好可讀的方式(human-readable)打印出來,或是寫進一個文件,而標准輸入和標准輸出(鍵盤和顯示器)在程序的角度也是文件,所以程序的輸入輸出就是文件讀寫。
1,內置函數print()
Python2.7中是有print語句和內置print函數的,而在Python3.3中,已經沒有print語句了,只有print函數,而其實以前的print語句的功能就是print函數默認形式的功能,所以我們在這里就只看看Python3.3中的內置函數print()。
函數原型
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
flush=False是Python3.3加上去的參數。
objects中每一個對象都會被轉化為string的形式,然后寫到file指定的文件中,默認是標准輸出(sys.stdout),每一個對象之間用sep分隔,默認是空格;所有對象都寫到文件后,會寫入end,默認是換行。
一個例子,我們對sep和end作了修改
1 from __future__ import print_function #Python2.7中使用print()函數,Python3.2中這行代碼就不需要了 2 d = {1:'a', 2:'b'} 3 t = (4, 5, 6) 4 l = ['love', 'happiness'] 5 print(d, t, l, sep='~', end='^_^\n')
我們已經知道d,t,l會被打包成一個tuple,賦給objects。如果對於print函數定義以及調用方式不熟悉,參見另一片博文[Python基礎-函數]
程序輸出
{1: 'a', 2: 'b'}~(4, 5, 6)~['love', 'happiness']^_^
[注意] 以上代碼用的Python2.7去解釋運行,在Python2.7中,默認print會應用到print語句,如果想禁用print語句而使用print()內置函數,這必須從__future__中引入print_function,即第一行語句。
2,把object轉化為str的形式,str()和repr()
在Python中,字符串(strings)是由內置類str代表的,這是一個類。同時Python還有內置函數str()。
輸入輸出都是以字符串的形式,print()就是把非str的object轉化為其str的形式輸出。那么Python怎么把一個object轉化為str的形式呢,Python會把這個object傳給內置str()函數。
str()回去尋找這個對象的__str__()屬性,如果這個對象沒有__str__()屬性,str()會調用repr()來得到結果。
一個例子,自定義的類,定義了__str__()函數
1 class wy: 2 def __str__(self): 3 return "abc" 4 5 w = wy() 6 print(w)
輸出:abc
如果沒有定義__str__(),則會調用repr(wy),會輸出:
<__main__.wy2 instance at 0x7f900d0c8050>
3,文件輸入輸出
使用內置函數open()得到一個文件對象(file object)。
open(filename, mode='r')
mode可以有如下形式:'r'-讀;'w'-寫;'a'-從文件末尾追加(appending);'r+' -讀寫;'w+'-讀寫(文件不存在時會創建);讀寫二進制(binary mode)文件時,加上'b'
文件對象的方法屬性:
f.read(size) 返回最多size個字節的str,當size缺省或為負值時,整個文件內容都被作為一個str讀出來,若到文末,返回空串' '
f.readline() 返回文件中一行的str,末尾加上換行符'\n'
f.write(string) 將string寫入file,返回成功寫入的字符個數。
f.close() 文件對象使用完一定要close()掉。
f.seek(offset, from_what) 改變文件對象的位置(position),offset為偏移量,from_what為參考位置,為0時從文件開頭, 為1時使用當前的文件位置,為2是使用文件末尾位置。from_what默認為0
按行從文件中讀取,有一種簡便的方式
1 f = open("print.py", "r+") 2 for line in f: #line的結尾會自動有一個“\n" 3 print(line, end=" ") #所以end=' ', 默認會又輸出換行符
例子,把print.py中的內容讀出來,寫到一個新文件中,在打印出來。
1 f = open("print.py", "r") 2 f2 = open("wyfile", "w+") #使用w+文件不存在時候才會創建 3 for line in f: 4 f2.write(line) 5 f2.seek(0) #這行語句之前,f2的位置在文末,所以必須調整到文件開頭。 6 print(f2.read(), end=' ')
7 f.close() #記住要釋放
8 f2.colse()
4,標准庫pickle模塊
我們已經知道輸入輸出都是字符串,要把一個對象存進文件,要將其轉化為字符串;從文件中讀出來的也是字符串,如果我們再要構建對象,則從讀出來的字符串去做。
那如果我們並不在乎文件存儲對象的形式,只想得到一個字符串去代表對象,用於存儲,或用於網絡傳遞,有沒有更好的方法呢?
有的,這就是Python標准庫的pickle模塊。pickle模塊提供了一套算法,用於對一個Python對象進行serializing(序列化為字符串)和de-serializing(從字符串構建對象),這個過程叫做pickle和unpickle。
pickle模塊兩個最常用的方法
pickle.dump(object, file) 將object序列化進file
pickle.load(file) 從file中解出當前位置的下一個對象
一個例子,簡單的試驗和測試了一下pickle模塊。
0 import pickle
1 d = {1:'a', 2:'b', 3:'c'} 2 f = open("newfile", "wb+") 3 pickle.dump(d, f) 4 del d[2] 5 pickle.dump(d, f) 6 f.seek(0) 7 d2 = pickle.load(f) #這里說明pickle可以區別出一個對象和另一個對象 8 d3 = pickle.load(f) 9 print(d2, d3)
close(f)
使用Python2.7運行,輸出結果:
({1: 'a', 2: 'b', 3: 'c'}, {1: 'a', 3: 'c'})
那么文件"newfile"中是些什么內容呢,cat newfile得到如下東西
(dp0
I1
S'a'
p1
sI2
S'b'
p2
sI3
S'c'
p3
s.(dp0
I1
S'a'
p1
sI3
S'c'
p2
不太看得明白這是兩個dict對象吧,可以看出,pickle確實使用了一些算法。
[題外]在寫上面這個測試例子的時候,我開始運行的時候,始終報錯,說pickle模塊沒有dump這個方法,后來google了一下,在stackoverflow上找到了答案,是我把文件名取為了pickle.py,所以根本沒有import進標准的pickle模塊,改了就好了,見參考3
參考:
1,http://docs.python.org/3.3/tutorial/inputoutput.html Python文檔
2,http://docs.python.org/3.2/library/pickle.html
3,http://stackoverflow.com/questions/3558718/how-do-i-pickle-an-object Stackoverflow上問題