Python学习笔记:输入和输出
本文來自:入門指南
開胃菜參考:開胃菜
使用Python解釋器:使用Python解釋器
本文對Python的簡介:Python簡介
Python流程介紹:深入Python流程
Python數(shù)據結構:Python數(shù)據結構
Python:模塊:Python模塊
目錄:
- 目錄:
- 7. 輸入和輸出
- 7.1. 格式化輸出
- 7.1.1. 舊式的字符串格式化
- 7.2. 文件讀寫
- 7.2.1. 文件對象方法
- 7.2.2. 使用 json 存儲結構化數(shù)據
- Note
- See also
7. 輸入和輸出
一個程序可以有幾種輸出方式:以人類可讀的方式打印數(shù)據,或者寫入一個文件供以后使用。本章將討論幾種可能性。
7.1. 格式化輸出
我們有兩種大相徑庭地輸出值方法:表達式語句 和 print() 函數(shù)(第三種訪求是使用文件對象的 write() 方法,標準文件輸出可以參考 sys.stdout,詳細內容參見庫參考手冊)。
通常,你想要對輸出做更多的格式控制,而不是簡單的打印使用空格分隔的值。有兩種方法可以格式化你的輸出:第一種方法是由你自己處理整個字符串,通過使用字符串切割和連接操作可以創(chuàng)建任何你想要的輸出形式。string 類型包含一些將字符串填充到指定列寬度的有用操作,隨后就會討論這些。第二種方法是使用 str.format() 方法。
標準模塊 string 包括了一些操作,將字符串填充入給定列時,這些操作很有用。隨后我們會討論這部分內容。第二種方法是使用 Template 方法。
當然,還有一個問題,如何將值轉化為字符串?很幸運,Python 有辦法將任意值轉為字符串:將它傳入 repr() 或 str() 函數(shù)。
函數(shù) str() 用于將值轉化為適于人閱讀的形式,而 repr() 轉化為供解釋器讀取的形式(如果沒有等價的語法,則會發(fā)生 SyntaxError 異常)某對象沒有適于人閱讀的解釋形式的話,str() 會返回與 repr() 等同的值。很多類型,諸如數(shù)值或鏈表、字典這樣的結構,針對各函數(shù)都有著統(tǒng)一的解讀方式。字符串和浮點數(shù),有著獨特的解讀方式。
下面有些例子:
>>> s = 'Hello, world.' >>> str(s) 'Hello, world.' >>> repr(s) "'Hello, world.'" >>> str(1/7) '0.14285714285714285' >>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...' >>> print(s) The value of x is 32.5, and y is 40000... >>> # The repr() of a string adds string quotes and backslashes: ... hello = 'hello, world\n' >>> hellos = repr(hello) >>> print(hellos) 'hello, world\n' >>> # The argument to repr() may be any Python object: ... repr((x, y, ('spam', 'eggs'))) "(32.5, 40000, ('spam', 'eggs'))"有兩種方式可以寫平方和立方表:
>>> for x in range(1, 11): ... print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ') ... # Note use of 'end' on previous line ... print(repr(x*x*x).rjust(4)) ...1 1 12 4 83 9 274 16 645 25 1256 36 2167 49 3438 64 5129 81 729 10 100 1000>>> for x in range(1, 11): ... print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)) ...1 1 12 4 83 9 274 16 645 25 1256 36 2167 49 3438 64 5129 81 729 10 100 1000(注意第一個例子,print() 在每列之間加了一個空格,它總是在參數(shù)間加入空格。)
以上是一個 str.rjust() 方法的演示,它把字符串輸出到一列,并通過向左側填充空格來使其右對齊。類似的方法還有 str.ljust() 和 str.center()。這些函數(shù)只是輸出新的字符串,并不改變什么。如果輸出的字符串太長,它們也不會截斷它,而是原樣輸出,這會使你的輸出格式變得混亂,不過總強過另一種選擇(截斷字符串),因為那樣會產生錯誤的輸出值(如果你確實需要截斷它,可以使用切割操作,例如:x.ljust(n)[:n] )。
還有另一個方法, str.zfill() 它用于向數(shù)值的字符串表達左側填充 0。該函數(shù)可以正確理解正負號:
>>> '12'.zfill(5) '00012' >>> '-3.14'.zfill(7) '-003.14' >>> '3.14159265359'.zfill(5) '3.14159265359'方法 str.format() 的基本用法如下:
>>> print('We are the {} who say "{}!"'.format('knights', 'Ni')) We are the knights who say "Ni!"大括號和其中的字符會被替換成傳入 str.format() 的參數(shù)。大括號中的數(shù)值指明使用傳入 str.format() 方法的對象中的哪一個:
>>> print('{0} and {1}'.format('spam', 'eggs')) spam and eggs >>> print('{1} and {0}'.format('spam', 'eggs')) eggs and spam如果在 str.format() 調用時使用關鍵字參數(shù),可以通過參數(shù)名來引用值:
>>> print('This {food} is {adjective}.'.format( ... food='spam', adjective='absolutely horrible')) This spam is absolutely horrible.位置參數(shù)和關鍵字參數(shù)可以隨意組合:
>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',other='Georg')) The story of Bill, Manfred, and Georg.‘!a’ (應用 ascii()),’!s’ (應用 str() )和 ‘!r’ (應用 repr() )可以在格式化之前轉換值:
>>> import math >>> print('The value of PI is approximately {}.'.format(math.pi)) The value of PI is approximately 3.14159265359. >>> print('The value of PI is approximately {!r}.'.format(math.pi)) The value of PI is approximately 3.141592653589793.字段名后允許可選的 ‘:’ 和格式指令。這允許對值的格式化加以更深入的控制。下例將 Pi 轉為三位精度。
>>> import math >>> print('The value of PI is approximately {0:.3f}.'.format(math.pi)) The value of PI is approximately 3.142.在字段后的 ‘:’ 后面加一個整數(shù)會限定該字段的最小寬度,這在美化表格時很有用:
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} >>> for name, phone in table.items(): ... print('{0:10} ==> {1:10d}'.format(name, phone)) ... Jack ==> 4098 Dcab ==> 7678 Sjoerd ==> 4127如果你有個實在是很長的格式化字符串,不想分割它。如果你可以用命名來引用被格式化的變量而不是位置就好了。有個簡單的方法,可以傳入一個字典,用中括號( ‘[]’ )訪問它的鍵:
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; ''Dcab: {0[Dcab]:d}'.format(table)) Jack: 4098; Sjoerd: 4127; Dcab: 8637678也可以用 ‘**’ 標志將這個字典以關鍵字參數(shù)的方式傳入:
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)) Jack: 4098; Sjoerd: 4127; Dcab: 8637678這種方式與新的內置函數(shù) vars() 組合使用非常有效。該函數(shù)返回包含所有局部變量的字典。
要進一步了解字符串格式化方法 str.format(),參見 格式字符串語法。
7.1.1. 舊式的字符串格式化
操作符 % 也可以用于字符串格式化。它以類似 sprintf()-style 的方式解析左參數(shù),將右參數(shù)應用于此,得到格式化操作生成的字符串,例如:
>>> import math >>> print('The value of PI is approximately %5.3f.' % math.pi) The value of PI is approximately 3.142.更多的信息可以參見 printf-style String Formatting 一節(jié)。
7.2. 文件讀寫
函數(shù) open() 返回 文件對象,通常的用法需要兩個參數(shù):open(filename, mode)。
>>> f = open('workfile', 'w')第一個參數(shù)是一個含有文件名的字符串。第二個參數(shù)也是一個字符串,含有描述如何使用該文件的幾個字符。mode 為 ‘r’ 時表示只是讀取文件;’w’ 表示只是寫入文件(已經存在的同名文件將被刪掉);’a’ 表示打開文件進行追加,寫入到文件中的任何數(shù)據將自動添加到末尾。 ‘r+’ 表示打開文件進行讀取和寫入。mode 參數(shù)是可選的,默認為 ‘r’。
通常,文件以 文本 打開,這意味著,你從文件讀出和向文件寫入的字符串會被特定的編碼方式(默認是UTF-8)編碼。模式后面的 ‘b’ 以 二進制模式 打開文件:數(shù)據會以字節(jié)對象的形式讀出和寫入。這種模式應該用于所有不包含文本的文件。
在文本模式下,讀取時默認會將平臺有關的行結束符(Unix上是 \n , Windows上是 \r\n)轉換為 \n。在文本模式下寫入時,默認會將出現(xiàn)的 \n 轉換成平臺有關的行結束符。這種暗地里的修改對 ASCII 文本文件沒有問題,但會損壞 JPEG 或 EXE 這樣的二進制文件中的數(shù)據。使用二進制模式讀寫此類文件時要特別小心。
7.2.1. 文件對象方法
本節(jié)中的示例都默認文件對象 f 已經創(chuàng)建。
要讀取文件內容,需要調用 f.read(size),該方法讀取若干數(shù)量的數(shù)據并以字符串形式返回其內容,size 是可選的數(shù)值,指定字符串長度。如果沒有指定 size 或者指定為負數(shù),就會讀取并返回整個文件。當文件大小為當前機器內存兩倍時,就會產生問題。反之,會盡可能按比較大的 size 讀取和返回數(shù)據。如果到了文件末尾,f.read() 會返回一個空字符串(”):
f.read()
‘This is the entire file.\n’
f.read()
”
f.readline() 從文件中讀取單獨一行,字符串結尾會自動加上一個換行符( \n ),只有當文件最后一行沒有以換行符結尾時,這一操作才會被忽略。這樣返回值就不會有混淆,如果 f.readline() 返回一個空字符串,那就表示到達了文件末尾,如果是一個空行,就會描述為 ‘\n’,一個只包含換行符的字符串:
>>> f.readline() 'This is the first line of the file.\n' >>> f.readline() 'Second line of the file\n' >>> f.readline() ''你可以循環(huán)遍歷文件對象來讀取文件中的每一行。這是一種內存高效、快速,并且代碼簡介的方式:
>>> for line in f: ... print(line, end='') ... This is the first line of the file. Second line of the file如果你想把文件中的所有行讀到一個列表中,你也可以使用 list(f) 或者 f.readlines()。
f.write(string) 方法將 string 的內容寫入文件,并返回寫入字符的長度:
>>> f.write('This is a test\n') 15想要寫入其他非字符串內容,首先要將它轉換為字符串:
>>> value = ('the answer', 42) >>> s = str(value) >>> f.write(s) 18f.tell() 返回一個整數(shù),代表文件對象在文件中的指針位置,該數(shù)值計量了自文件開頭到指針處的比特數(shù)。需要改變文件對象指針話話,使用 f.seek(offset,from_what)。指針在該操作中從指定的引用位置移動 offset 比特,引用位置由 from_what 參數(shù)指定。 from_what 值為 0 表示自文件起始處開始,1 表示自當前文件指針位置開始,2 表示自文件末尾開始。from_what 可以忽略,其默認值為零,此時從文件頭開始:
>>> f = open('workfile', 'rb+') >>> f.write(b'0123456789abcdef') 16 >>> f.seek(5) # Go to the 6th byte in the file 5 >>> f.read(1) b'5' >>> f.seek(-3, 2) # Go to the 3rd byte before the end 13 >>> f.read(1) b'd'在文本文件中(沒有以 b 模式打開),只允許從文件頭開始尋找(有個例外是用 seek(0, 2) 尋找文件的最末尾處)而且合法的 偏移 值只能是 f.tell() 返回的值或者是零。其它任何 偏移 值都會產生未定義的行為。
當你使用完一個文件時,調用 f.close() 方法就可以關閉它并釋放其占用的所有系統(tǒng)資源。 在調用 f.close() 方法后,試圖再次使用文件對象將會自動失敗。
>>> f.close() >>> f.read() Traceback (most recent call last):File "<stdin>", line 1, in ? ValueError: I/O operation on closed file用關鍵字 with 處理文件對象是個好習慣。它的先進之處在于文件用完后會自動關閉,就算發(fā)生異常也沒關系。它是 try-finally 塊的簡寫:
>>> with open('workfile', 'r') as f: ... read_data = f.read() >>> f.closed True文件對象還有一些不太常用的附加方法,比如 isatty() 和 truncate() 在庫參考手冊中有文件對象的完整指南。
7.2.2. 使用 json 存儲結構化數(shù)據
從文件中讀寫字符串很容易。數(shù)值就要多費點兒周折,因為 read() 方法只會返回字符串,應將其傳入 int() 這樣的函數(shù),就可以將 ‘123’ 這樣的字符串轉換為對應的數(shù)值 123。當你想要保存更為復雜的數(shù)據類型,例如嵌套的列表和字典,手工解析和序列化它們將變得更復雜。
好在用戶不是非得自己編寫和調試保存復雜數(shù)據類型的代碼,Python 允許你使用常用的數(shù)據交換格式 JSON(JavaScript Object Notation)。標準模塊 json 可以接受 Python 數(shù)據結構,并將它們轉換為字符串表示形式;此過程稱為 序列化。從字符串表示形式重新構建數(shù)據結構稱為 反序列化。序列化和反序列化的過程中,表示該對象的字符串可以存儲在文件或數(shù)據中,也可以通過網絡連接傳送給遠程的機器。
Note
JSON 格式經常用于現(xiàn)代應用程序中進行數(shù)據交換。許多程序員都已經熟悉它了,使它成為相互協(xié)作的一個不錯的選擇。
如果你有一個對象 x,你可以用簡單的一行代碼查看其 JSON 字符串表示形式:
>>> json.dumps([1, 'simple', 'list']) '[1, "simple", "list"]'dumps() 函數(shù)的另外一個變體 dump(),直接將對象序列化到一個文件。所以如果 f 是為寫入而打開的一個 文件對象,我們可以這樣做:
json.dump(x, f)為了重新解碼對象,如果 f 是為讀取而打開的 文件對象:
x = json.load(f)這種簡單的序列化技術可以處理列表和字典,但序列化任意類實例為 JSON 需要一點額外的努力。 json 模塊的手冊對此有詳細的解釋。
See also
pickle - pickle 模塊
與 JSON 不同,pickle 是一個協(xié)議,它允許任意復雜的 Python 對象的序列化。因此,它只能用于 Python 而不能用來與其他語言編寫的應用程序進行通信。默認情況下它也是不安全的:如果數(shù)據由熟練的攻擊者精心設計, 反序列化來自一個不受信任源的 pickle 數(shù)據可以執(zhí)行任意代碼。
總結
以上是生活随笔為你收集整理的Python学习笔记:输入和输出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx 防止恶意域名解析_配置ngi
- 下一篇: html遮罩层模态提示,页面遮罩层,并且