Python的"print"函數在「Hello World」之外的延伸
想必任何一個人學習python的第一件事就是學習怎麼去輸出字元串「hello world」,就像你期望的那樣,這段代碼是非常簡潔的: 確實,python的「print」函數用起來非常簡單直接以至於我們很少對它進行一些思考。我們猜測人們知道如何使用它——而且多數情況下,對於人們想要去做的事,這也是正確的。
但隱藏在「print」功能表面之下還有許多功能,以及一些歷史(甚至有點痛苦)。了解如何使用「列印」可以減少你編寫的代碼,而且通常也會讓它對於你來說更加容易使用。
原理
基本原理很簡單:「print」是一個函數,這意味著如果要調用它,需要使用括弧:
您可以將任何類型的數據傳遞給「print」。字元串是最常見的,但也可以是int、float、list、tuples、dict、set或任何其他對象。例如:
或者:
當然,這跟你要傳遞的參數是無關的,不論是對象字面量或是引用一個變數
你也可以將表達式放在括弧內;表達式的值將傳遞給「print」:
在「print」顯示其輸出之後,它添加了一個新行。例如
您可以傳遞任意多的參數來「列印」,將參數用逗號分隔,每一個參數都會按照順序列印出來,參數中間會有一個空格:
下面我們將看到如何更改這兩個默認行為。
輸入和輸出
如果「print」是一個函數,那麼他一定會有返回值,我們看:
換句話說:不管你列印的是什麼,「print」都不會有返回值。畢竟你不是為了得到返回值而列印的,而是為了它的另一個作用。
那麼「print」的實參呢?已經看到我們可以傳遞任意數量的實參,它們都會被列印出來。但是有一些可選的形參我們也是可以傳遞的。
改變輸出項之間的字元串顯示和改變放在輸出末尾的代碼,這兩點是聯繫非常緊密的,他們可以讓我們自定義我們在前面看到的行為。
例如,參數「sep」,默認為「」(空格字元),被放在列印項之間。我們可以將其設置為任何字元串,包括多字元字元串:
請注意,「sep」放在「print」的參數之間,而不是參數的每個元素之間。因此,在第三個示例中,「**」位於列表之間,而不是列表的整數元素之間。
如果你想讓列印的參數一次相連,可以把「sep」設為空字元串:
類似的,參數「end」的默認值是「
」(換行),但是可以包含任意字元串。他決定了在「print」結束之後列印什麼。
例如,如果你想在你列印之後額外空幾行出來,就改一下「end」的值就會產生新行:
但是,反過來講如果你不想在輸出之後加新行,吧「end」的值設成空字元串就可以了:
注意,在python交互命令行中,使用空字元串列印內容意味著下一個「>>>」提示出現在所列印內容之後。畢竟,您並沒有要求在您所寫的內容之後有一個新行,而python遵從了您的請求。
當然,你可以傳遞根本不涉及換行的「end」值。例如,假設您希望將多個欄位輸出到屏幕,每個欄位列印在一行中:
默認情況下,「print」將其數據發送到標準輸出,在python中稱為「sys.stdout」。當「sys」模塊與python一起自動載入時,它的名稱不可用,除非你明確了「import sys」。
「print」函數允許您使用「file」參數指定要寫入的另一個類似文件的對象(即,遵循適當協議的對象)。對象必須是可寫的,除此之外,您可以使用任何對象。
例如:
在這種情況下,輸出被寫入一個文件。但我們也可以寫入一個Stringio對象,例如,它的行為類似於一個文件,但不是一個文件。
注意,如果我在上面的示例中沒有關閉「f」,輸出就不會到達文件中。這是因為默認情況下,python會緩衝所有輸出;每當寫入文件時,只有當緩衝區填滿(並刷新)時,顯式調用「flush」方法時,或關閉文件時(從而隱式刷新)才實際寫入數據。將「with」結構與文件對象一起使用就會關閉它,從而刷新緩衝區。
但是,還有另一種刷新輸出緩衝區的方法:我們可以將一個True值傳遞給「print」中的「flush」參數。在這種情況下,輸出會立即刷新到磁碟,然後寫入。這聽起來不錯,但請記住,緩衝的目的是減少磁碟和計算機I/O系統上的負載。所以需要的時候才能刷新,但不要一直這樣做——除非你是按小時付錢的,而且更慢些對你有好處。
下面是一個有或無沖洗的列印示例:
您可能注意到這裡有一個小的不一致:「print」寫入文件,默認情況下為「sys.stdout」。如果我們不刷新或關閉文件,輸出將被緩衝。那麼,當我們列印到屏幕上時,為什麼不需要衝洗(或者關閉,這不是一個好主意)?
答案是「sys.stdout」是由python專門處理的。正如python文檔所說,它是「行緩衝的」,這意味著每次發送換行符(「
」)時,都會刷新輸出。只要你把東西列印到「sys.stdout」就會以新行結尾——為什麼不這樣做呢?——你不會注意到緩存。
還記得Python2嗎?
在我寫這篇文章的時候,是2019年1月,距離不再支持或維護python 2之前還有不到12個月的時間。這並沒有改變我的許多客戶仍在使用python 2的事實(因為重寫大型代碼庫既不可行也不值得)。如果您仍在使用python 2,那麼應該嘗試轉移到python 3。
事實上,讓用戶從python 2到3的因素之一就是「列印」的不同。
首先,python2中的「print」是一個語句,而不是表達式。這意味著2中的括弧是可選的,而3中的括弧是強制的——當人們從2移動到3時,首先要學習的內容之一。
這也意味著在python2中「print」不能傳遞給其他函數。在Python3中是可以的。
python 2的「print」語句沒有可以處理的參數(或默認值)。你想列印到文件而不是「sys.stdout」?將其分配給「sys.stdout」以使用「print」——或者只使用文件的「write」方法寫入文件。你想讓「列印」在列印後降行?在行尾加一個逗號。(是的,這是真的;這很難看,但是管用。)
如果您正在使用python 2,並且想體驗一下python 3的列印功能,那該怎麼辦?您可以將此行添加到代碼中:
from __future__ import print_function
一旦您這樣做了,python 3的「print」函數就會就位。
現在我知道python 3已經不是將來時了;實際上,您可以說python 2已經過時了。但對於許多想轉型或學習如何轉型的人來說,這是一個很好的方法。但是要當心:如果您有不帶括弧的「列印」調用,或者是避免行換行的逗號,那麼您需要做的不僅僅是這個導入。您需要檢查您的代碼,並確保它以這種方式工作。所以這看起來是一個明智的方法,是一個大的過渡階段你需要做的第一步,從2到3。
英文原文:https://blog.lerner.co.il/beyond-the-hello-world-of-pythons-print-function/
譯者:遊騎兵
TAG:Python程序員 |