天天看點

Python3 輸入和輸出

Python有兩種較為常用的輸出方式::表達式語句和 print() 函數。 

第三種方式則是使用檔案對象的 write() 方法,标準輸出檔案可以使用sys.stdout 。 

如果你希望輸出的形式更加多樣,可以使用 str.format() 函數來格式化輸出值。 

如果你希望将輸出的值轉成字元串,可以使用 repr() 或 str() 函數來實作。

str(): 函數傳回一個使用者易讀的表達形式。

repr(): 産生一個解釋器易讀的表達形式。 

例如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<code>&gt;&gt;&gt; s </code><code>=</code> <code>'Hello'</code>

<code>&gt;&gt;&gt; </code><code>str</code><code>(s)   </code><code># 傳回一個使用者易讀的表達形式</code>

<code>'Hello'</code>

<code>&gt;&gt;&gt; </code><code>repr</code><code>(s)  </code><code># 産生一個解釋器易讀的表達形式</code>

<code>"'Hello'"</code>

<code>&gt;&gt;&gt; </code><code>str</code><code>(</code><code>1</code><code>/</code><code>7</code><code>)</code>

<code>'0.14285714285714285'</code>

<code>&gt;&gt;&gt; x </code><code>=</code> <code>10</code> <code>*</code> <code>3.25</code>

<code>&gt;&gt;&gt; y </code><code>=</code> <code>200</code> <code>*</code> <code>200</code>

<code>&gt;&gt;&gt; s </code><code>=</code> <code>'x 的值為: '</code> <code>+</code> <code>repr</code><code>(x) </code><code>+</code> <code>',  y 的值為:'</code> <code>+</code> <code>repr</code><code>(y) </code><code>+</code> <code>'...'</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(s)</code>

<code>x 的值為: </code><code>32.5</code><code>,  y 的值為:</code><code>40000.</code><code>..</code>

<code>&gt;&gt;&gt; </code><code>#  repr() 函數可以轉義字元串中的特殊字元</code>

<code>... hello </code><code>=</code> <code>'hello\n'</code>

<code>&gt;&gt;&gt; hello2 </code><code>=</code> <code>repr</code><code>(hello)</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(hello2)</code>

<code>'hello\n'</code>

<code>&gt;&gt;&gt; </code><code># repr() 的參數可以是 Python 的任何對象</code>

<code>... </code><code>repr</code><code>((x, y, (</code><code>'Google'</code><code>, </code><code>'Baidu'</code><code>)))</code>

<code>"(32.5, 40000, ('Google', 'Baidu'))"</code>

str.format() 的基本使用如下:

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>'{}網址:"{}!"'</code><code>.</code><code>format</code><code>(</code><code>'zero'</code><code>,</code><code>'www.zero01.org'</code><code>))  </code><code># 一個大括号對應一個字元串</code>

<code>zero網址:</code><code>"www.zero01.org!"</code>

大括号及其裡面的字元 (稱作格式化字段) 将會被 format() 中的參數替換。 

在括号中的數字用于指向傳入對象在 format() 中的位置,如下所示:

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>'{0} 和 {1} 不是好朋友'</code><code>.</code><code>format</code><code>(</code><code>'小明'</code><code>, </code><code>'小紅'</code><code>))</code>

<code>小明 和 小紅 不是好朋友</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>'{1} 和 {0} 不是好朋友'</code><code>.</code><code>format</code><code>(</code><code>'小明'</code><code>, </code><code>'小紅'</code><code>))</code>

<code>小紅 和 小明 不是好朋友</code>

如果在 format() 中使用了關鍵字參數, 那麼它們的值會指向使用該名字的參數。

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>'{name}網址:"{host}!"'</code><code>.</code><code>format</code><code>(name</code><code>=</code><code>'zero'</code><code>,host</code><code>=</code><code>'www.zero01.org'</code><code>))</code>

可以将以上兩種使用方法結合一起使用:

<code># 索引要使用在參數的前面</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>'{0}{name}網址:"{host}"!'</code><code>.</code><code>format</code><code>(</code><code>'Test:'</code><code>,name</code><code>=</code><code>'zero'</code><code>,host</code><code>=</code><code>'www.zero01.org'</code><code>))</code>

<code>Test:zero網址:</code><code>"www.zero01.org"</code><code>!</code>

使用以下幾個字元可以在格式化某個值之前對其進行轉化:

!a 等于調用了 ascii( ) 函數進行轉化

!s 等于調用了 str( ) 函數進行轉化

!r 等于調用了 repr( ) 函數進行轉化

代碼示例:

<code>print</code><code>(</code><code>'{!a}'</code><code>.</code><code>format</code><code>(</code><code>'hello'</code><code>))</code>

<code>print</code><code>(</code><code>'{!s}'</code><code>.</code><code>format</code><code>(</code><code>'hello'</code><code>))</code>

<code>print</code><code>(</code><code>'{!r}'</code><code>.</code><code>format</code><code>(</code><code>'hello'</code><code>))</code>

運作結果:

‘hello’   hello   ‘hello’

如果我們要保留n位小數時,可以使用冒号 ’ : ’ 來進行指定保留幾位小數,例如下面的示例将 Pi 保留三位小數:

<code>import</code> <code>math</code>

<code># f的作用是表示這個是個浮點數類型</code>

<code>print</code><code>(</code><code>'保留三位小數的PI:{0:.3f}'</code><code>.</code><code>format</code><code>(math.pi))</code>

保留三位小數的PI:3.142

在 ‘:’ 後傳入一個整數, 可以保證該域至少有這麼多的寬度。 用于美化表格時很有用。

<code>&gt;&gt;&gt; table </code><code>=</code> <code>{</code><code>'Google'</code><code>: </code><code>1</code><code>, </code><code>'Runoob'</code><code>: </code><code>2</code><code>, </code><code>'Taobao'</code><code>: </code><code>3</code><code>}</code>

<code>&gt;&gt;&gt; </code><code>for</code> <code>name, number </code><code>in</code> <code>table.items():</code>

<code>...     </code><code>print</code><code>(</code><code>'{0:10} ==&gt; {1:10d}'</code><code>.</code><code>format</code><code>(name, number))</code>

<code>...</code>

<code>Runoob     </code><code>=</code><code>=</code><code>&gt;          </code><code>2</code>

<code>Taobao     </code><code>=</code><code>=</code><code>&gt;          </code><code>3</code>

<code>Google     </code><code>=</code><code>=</code><code>&gt;          </code><code>1</code>

如果你有一個很長的格式化字元串, 而你不想将它們分開, 那麼在格式化時通過變量名而非位置會是很好的事情。 

最簡單的就是傳入一個字典, 然後使用方括号 ‘[]’ 來通路鍵值 :

<code># d是用來接收整型數值的</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>'Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'</code><code>.</code><code>format</code><code>(table))</code>

<code>Runoob: </code><code>2</code><code>; Google: </code><code>1</code><code>; Taobao: </code><code>3</code>

% 操作符也可以實作字元串格式化。 它将左邊的參數作為類似 sprintf() 式的格式化字元串, 而将右邊的代入, 然後傳回格式化後的字元串. 例如:

<code>&gt;&gt;&gt; </code><code>import</code> <code>math</code>

<code>&gt;&gt;&gt; </code><code>print</code><code>(</code><code>'常量 PI 的值近似為:%5.3f。'</code> <code>%</code> <code>math.pi)</code>

<code>常量 PI 的值近似為:</code><code>3.142</code><code>。</code>

因為 str.format() 比較新的函數, 大多數的 Python 代碼仍然使用 % 操作符。但是因為這種舊式的格式化最終會從該語言中移除, 應該更多的使用 str.format(),是以了解一下即可。

Python提供了一個内置函數 input() ,可以從标準輸入讀入一行文本,預設的标準輸入是鍵盤,在PyCharm工具中使用這個函數就可以允許你從控制台中進行輸入。 

input 可以接收一個Python表達式作為輸入,并将運算結果傳回。

<code>str</code> <code>=</code> <code>input</code><code>(</code><code>"請輸入:"</code><code>)</code>

<code>print</code> <code>(</code><code>"你輸入的内容是: "</code><code>, </code><code>str</code><code>)</code>

這會産生如下的對應着輸入的結果:

 請輸入:hello   你輸入的内容是:  hello

如果你要通過鍵盤的輸入進行一個運算的話,需要把類型轉換成數字類型,例如:

<code>num</code><code>=</code><code>int</code><code>(</code><code>input</code><code>(</code><code>"請輸入:"</code><code>))</code>

<code>print</code><code>(</code><code>"輸入的數字平方是:"</code><code>,num</code><code>*</code><code>num)</code>

 請輸入:3   輸入的數字平方是: 9

如果不轉類型的話,會按照字元串類型去進行運算,是以結果當然是錯誤的,錯誤示例:

<code>num</code><code>=</code><code>input</code><code>(</code><code>"請輸入:"</code><code>)</code>

<code>print</code><code>(</code><code>"輸入的數字乘以二是:"</code><code>,num</code><code>*</code><code>2</code><code>)</code>

 輸入的數字乘以二是: 33

在python中有一個内置的 open( ) 函數,這個函數可以用于打開某個檔案進行讀寫操作,此函數會傳回一個file對象,基本文法格式如下:

open(filename, mode)

filename 變量用于表示你要通路的檔案路徑。

mode則決定了打開檔案的模式:隻讀,寫入,追加等。所有可取值見如下的完全清單。這個參數是非強制的,如果提供參數的話,預設的檔案通路模式為隻讀(r)。

不同模式打開檔案的完全清單:

以下使用一個示例,示範将一段文字寫入到一個檔案中:

<code># 打開一個檔案,并指定通路模式為寫</code>

<code>output</code><code>=</code><code>open</code><code>(</code><code>"E:/test.txt"</code><code>,</code><code>"w"</code><code>)</code>

<code># 往這個檔案寫入一段文字,換行使用\n來換行</code>

<code>output.write(</code><code>"Python 是一個非常好的語言。\n是的,人生苦短我用python!!\n"</code><code>)</code>

<code># 關閉打開的檔案,不然會導緻資源占用</code>

<code>output.close()</code>

第一個參數為要打開的檔案名。

第二個參數描述檔案如何使用的字元。 mode 可以是 ‘r’ 如果檔案隻讀, ‘w’ 隻用于寫 (如果存在同名檔案則将被删除), 和 ‘a’ 用于追加檔案内容; 所寫的任何資料都會被自動增加到末尾. ‘r+’ 同時用于讀寫。 mode 參數是可選的; ‘r’ 将是預設值。

打開此檔案可以看到我們寫入的内容。

以下再使用一個示例,讀取我們剛剛寫入的那個檔案中的内容:

<code>file_str</code><code>=</code><code>open</code><code>(</code><code>"E:/test.txt"</code><code>)  </code><code># 參數為這個檔案的路徑</code>

<code>print</code><code>(file_str.readline()) </code><code># 使用此方法可以讀取一行文字,傳回值是一個字元串</code>

<code>print</code><code>(file_str.readline())</code>

<code>file_str.close()</code>

 Python 是一個非常好的語言。 是的,人生苦短我用python!!

上面已經介紹過兩個檔案對象的方法了,這兩個方法也是最主要的方法,一個用于寫檔案一個用于讀檔案。除了這兩個方法還有以下幾個方法:

read( size )   此方法有一個預設參數,這個參數用于定義這個方法一次讀取多少資料,機關是位元組。然後讀取的結果會作為字元串或位元組對象傳回。 

因為size 是一個可選的數字類型的參數,是以當 size 被忽略了或者為負, 那麼該檔案的所有内容都将被讀取并且傳回。

<code>file_str</code><code>=</code><code>open</code><code>(</code><code>"E:/test.txt"</code><code>)</code>

<code>str</code><code>=</code><code>file_str.read(</code><code>10</code><code>)</code>

<code>print</code><code>(</code><code>str</code><code>)</code>

Python 是一個

因為設定隻讀取10個位元組,是以檔案内容沒有被全部讀取出來。

如果想要讀取全部内容,就不需要指定這個參數:

<code>str</code><code>=</code><code>file_str.read()</code>

 Python 是一個非常好的語言。   是的,人生苦短我用python!!

readline( ) 這個方法上面的示例也使用過了,這個方法能按行讀取檔案内容,換行符為’ \n ’ 。如果此方法傳回了一個空字元串, 說明檔案已經讀完了。

<code>file_str </code><code>=</code> <code>open</code><code>(</code><code>"E:/test.txt"</code><code>)</code>

<code>while</code> <code>True</code><code>:</code>

<code>    </code><code>str</code> <code>=</code> <code>file_str.readline()</code>

<code>    </code><code>if</code> <code>str</code> <code>=</code><code>=</code> <code>"":</code>

<code>        </code><code>print</code><code>(</code><code>"檔案已經讀取完了!"</code><code>)</code>

<code>        </code><code>break</code>

<code>    </code><code>print</code><code>(</code><code>str</code><code>)</code>

Python 是一個非常好的語言。 檔案已經讀取完了!

readlines( )  此方法會以清單的形式傳回檔案中所有的行,此方法也有一個可選參數,此參數用于指定讀取的位元組長度,并且會将這些位元組按行分割。

<code>print</code><code>(</code><code>type</code><code>(file_str.readlines()))</code>

&lt;class 'list'&gt;

從結果可以看到傳回的對象類型是list清單。

我們可以通過周遊清單,來取出裡面的元素: 

<code>listfile</code><code>=</code><code>file_str.readlines()</code>

<code>print</code><code>(</code><code>"獲得的是一個清單:"</code><code>,listfile,</code><code>"\n"</code><code>)</code>

<code>print</code><code>(</code><code>"可以使用循環将清單中的内容周遊出來:"</code><code>)</code>

<code>for</code> <code>i </code><code>in</code> <code>listfile:</code>

<code>    </code><code>print</code><code>(i)</code>

獲得的是一個清單: [‘Python 是一個非常好的語言。\n’, ‘是的,人生苦短我用python!!\n’] 可以使用循環将清單中的内容周遊出來: 

這個方法并不常用,畢竟用 readline( ) 方法就可以了。

write( ) 此方法在之前的示例也用到過,可以将一段字元串内容寫入到某個指定的檔案中,如需換行得使用 \n 轉義符。但是如果想要将數字類型或者其他的非字元串類型寫入到檔案中,需要提前轉換成字元串類型:

<code>file_str </code><code>=</code> <code>open</code><code>(</code><code>"E:/test.txt"</code><code>, </code><code>"w"</code><code>)  </code><code># 設定為寫模式</code>

<code>data </code><code>=</code> <code>[</code><code>"TestNumber:"</code><code>, </code><code>123</code><code>, </code><code>45</code><code>, </code><code>12.5</code><code>]</code>

<code>outData </code><code>=</code> <code>str</code><code>(data)  </code><code># 轉換成字元串類型</code>

<code>file_str.write(outData)  </code><code># 寫入到檔案中</code>

<code>file_str.close()  </code><code># 記得一定要關閉資源</code>

tell( ) 此方法會告訴你目前讀取了多少個位元組,這個數字是從檔案開頭算起的位元組數。

<code>print</code><code>(file_str.read())</code>

<code>print</code><code>(</code><code>"讀取了:"</code><code>,file_str.tell(),</code><code>"個位元組"</code><code>)</code>

 [‘TestNumber:’, 123, 45, 12.5]   讀取了: 31 個位元組

seek( )  

如果要改變檔案目前的讀取位置, 可以使用 f.seek(offset, from_what) 函數。 

from_what 的值, 如果是 0 表示開頭, 如果是 1 表示目前位置, 2 表示檔案的結尾,例如: 

seek( x , 0 ) : 從起始位置即檔案首行首字元開始移動 x 個字元

seek( x , 1 ) : 表示從目前位置往後移動x個字元

seek( -x , 2 ):表示從檔案的結尾往前移動x個字元

from_what 值為預設為0,即檔案開頭。下面給出一個完整的例子:

<code># 以二進制格式打開一個檔案用于讀寫。檔案指針将會放在檔案的開頭。</code>

<code>file_str </code><code>=</code> <code>open</code><code>(</code><code>"E:/test.txt"</code><code>,</code><code>"rb+"</code><code>)</code>

<code>file_str.write(b</code><code>'0123456789'</code><code>)</code>

<code>print</code><code>(file_str.seek(</code><code>5</code><code>,</code><code>0</code><code>),end</code><code>=</code><code>" "</code><code>) </code><code># 移動到檔案的第六個位元組</code>

<code>print</code><code>(file_str.seek(</code><code>3</code><code>,</code><code>1</code><code>),end</code><code>=</code><code>" "</code><code>)  </code><code># 從目前的讀取位置移動三個位元組</code>

<code>print</code><code>(file_str.seek(</code><code>-</code><code>3</code><code>,</code><code>2</code><code>),end</code><code>=</code><code>" "</code><code>)  </code><code># 移動到檔案的倒數第三位元組</code>

5 8 7

close( ) 方法,從以上示範可以看到每一個示例代碼的末尾都調用了這個方法,這是因為要關閉對檔案的操作資源占用,如果不關閉的話,當程式運作時去打開這個檔案就會顯示檔案被占用。因為一個file對象調用close( ) 方法後就會關閉檔案并釋放系統資源,是以如果再嘗試通過該對象去進行讀寫檔案的操作,就會抛出異常。

<code>&gt;&gt;&gt; file_str </code><code>=</code> <code>open</code><code>(</code><code>"E:/test.txt"</code><code>)</code>

<code>&gt;&gt;&gt; file_str.close()</code>

<code>&gt;&gt;&gt; file_str.read()</code>

<code>Traceback (most recent call last):</code>

<code>  </code><code>File</code> <code>"&lt;stdin&gt;"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code>?</code>

<code>ValueError: I</code><code>/</code><code>O operation on closed </code><code>file</code>

    當處理一個file對象時, 使用 with 關鍵字是非常好的方式。在檔案讀寫操作結束後, 它會自動幫你正确的關閉檔案。這樣就不需要每次都使用finally最終塊來確定關閉資源了。 

<code># 需要使用as關鍵字來把file對象指派給一個變量,是以在這裡file_str是一個變量</code>

<code>&gt;&gt;&gt; with </code><code>open</code><code>(</code><code>"E:/test.txt"</code><code>) as file_str:</code>

<code>...     read_data </code><code>=</code> <code>file_str.read()</code>

<code>&gt;&gt;&gt; f.closed  </code><code># 如果資源關閉傳回出True,否則傳回False</code>

<code>True</code>

    從上面這個示例可以看到,我并沒有調用 close( ) 方法,with自動幫我正确的關閉了檔案,因為with的這一個友善之處,是以with關鍵字很常用。

檔案對象還有其他方法, 如 isatty() 和 trucate(), 但這些通常比較少用,就不贅述了。

    python的pickle子產品實作了基本的資料序列和反序列化。 

通過pickle子產品的序列化操作我們能夠将程式中運作的對象資訊儲存到檔案中去,永久存儲。 

通過pickle子產品的反序列化操作,我們能夠從檔案中建立上一次程式儲存的對象。 

簡單來說,pickle可以儲存和加載幾乎任何的python資料對象,例如清單、字典、元組等。我們可以通過pickle把這些資料對象存儲到檔案中(序列化),反過來(反序列化)也可以把檔案中儲存的這些資料再讀取到程式的記憶體中。

    pickle子產品提供了兩個方法,一個是 dump( ) 一個是 load( ) ,前者用于将資料對象儲存到檔案中,後者用于将儲存到檔案中的資料讀取到記憶體中。要注意的一點是:這種形式儲存的資料将會是二進制的形式,也就是說并非儲存為普通的文本檔案而是一個二進制檔案。

下面使用一個實際的例子來簡單的示範一下dump方法的應用方式,代碼示例:

因為是二進制形式的資料,是以用文本打開就會是一片亂碼。

然後再使用load方法,就可以将資料再讀取回來,并且資料類型依舊是清單,代碼示例:

 讀取出來的資料: [[‘test’, ‘file’], (‘dump’, 78), {‘name’: ‘lisi’}, ‘zero’, 12.5, 100]   該資料的類型是: &lt;class 'list'&gt;

pickle子產品主要就是像以上示例一樣,用于将某個資料對象儲存到檔案中,這樣就可以永久存儲,然後還可以再次将這些資料再讀取到記憶體中。

本文轉自 ZeroOne01 51CTO部落格,原文連結:http://blog.51cto.com/zero01/1980934,如需轉載請自行聯系原作者