摘要
標題已說明了一切——本 PEP 提議使用新的內置函數 print() 來替代 print 語句,並建議給此新函數使用特殊的簽名(signature )。
摘要
標題已說明了一切——本 PEP 提議使用新的內置函數 print() 來替代 print 語句,並建議給此新函數使用特殊的簽名(signature )。
原理闡述
print 語句 早就被列在了不可靠的語言特性列表中,例如 Guido 的“Python 之悔”(Python Regrets)演講【1】,並計劃在 Python 3000 版本移除。因此,本 PEP 的目的並不新鮮,儘管它可能會在 Python 開發人員中引起較大爭議。
以下對 print() 函數的爭議是提取自 Guido 本人的 Python-3000 消息【2】:
- print 是唯一的應用程序級功能,並擁有專屬的語句。在 Python 的世界裡,當某些任務在不通過編譯器的幫助就無法完成的情況下,語法(syntax)通常會被用作最後的手段。在這種異常情況下,print 並不合適。
- 在開發應用程序的時候,人們經常需要用更復雜的東西來代替 print 輸出,例如調用 logging,或者調用其它的 I/O 庫。至於 print() 函數,這是個直截了當的字符替換,如今它混搭了所有那些括號,還可能會轉換 >>stream 樣式的語法。
- 為 print 設置特殊的語法只會給進化帶來一個更加巨大的屏障,例如這有個猜想,一個新的 printf() 函數不用多久就會出現,跟 print() 函數共存。
- 當需要一個不同的分隔符(不是空格,或者沒有分隔符)時,沒有簡單的方法可以將 print 語句轉換成另一個調用。同樣地,使用其它一些分隔符而非空格時,根本無法方便地打印對象。
- 如果 print() 是個函數,就可以非常容易地在一個模塊內替換它(僅需 def print(*args):…),甚至可以在整個程序內替換(例如放一個不同的方法進 __builtin__.print)。實際上,要做到這點,還可以寫一個帶 write() 方法的類,然後定向給 sys.stdout ,這想法不錯,但無疑是一個非常巨大的概念飛躍,而且跟 print 相比,它工作在不同的層級。
設計規格
print() 的書寫方式取自各種郵件,最近發佈在 python-3000 列表裡的是【3】:
def print(*args, sep=' ', end='\\n', file=None)
調用像:
print(a, b, c, file=sys.stderr)
相當於當前的:
print >>sys.stderr, a, b, c
可選的 sep 與 end 參數相應地指定了每個打印參數之間及之後的內容。
softspace 功能(當前在文件上的半祕密屬性,用於告訴 print 是否要在第一個條目前插入空格)會被刪除。因此,當前版本的以下寫法不能被直接轉換:
print "a",
它不會在“a”與換行符之間打印一個空格。
(譯註:在 3.3 版本,print() 函數又做了改動,增加了默認參數 flush=False)
向後兼容性
本 PEP 中提出的改動將致使如今的 print 語句失效。只有那些恰好用括號包圍了所有參數的寫法才能在 Python 3 版本中生效,至於其它,只有加上了括號的值才能保持原樣打印。例如,在 2.x 中:
>>> print ("Hello")
Hello
>>> print ("Hello", "world")
('Hello', 'world')
而在 3.0 中:
>>> print ("Hello")
Hello
>>> print ("Hello", "world")
Hello world
幸運的是,因為 print 是 Python 2 中的一個語句,所以它可以被通過自動化工具而檢測到,並可靠而精確地替換掉,因此應該沒有重大的移植問題(如果有人來寫這個工具的話)。
實現
更改將在 Python 3000 分支中實現(修訂版從 53685 到 53704)。大多數在維庫代碼(legacy code)已經做轉換了,但要抓出發行版本中的每個 print 語句,還需要持續不斷地努力。