本文首發於編程派的微信公衆號。python
原做者:Brett Cannongit
原文連接:http://www.snarky.ca/why-print-became-a-function-in-python-3github
譯者:EarlGrey@編程派express
在Python 2中,print是一個語句(statement);而在Python 3中變成了函數(function)。不少Python用戶都會問,爲何Python 3將print變成了函數呢?本文就是Python核心開發者Brett Cannon對此的解釋。編程
今年初Python決定遷移到Github,就是由Brett Cannon徵求Python社區的意見後做出的。他對此也做出瞭解釋。微信
在Python 2中,print語句最簡單的使用形式就是print A
,這至關於執行了sys.stdout.write(str(A) + '\n')
。若是你以逗號爲分隔符,傳遞額外的參數(argument),這些參數會被傳遞至str()
函數,最終打印時每一個參數之間會空一格。例如,print A, B, C
至關於sys.stdout.write(' '.join(map(str, [A, B, C])) + '\n')
。若是print語句的最後再加上一個逗號,那麼就不會再添加斷行符(\n
),也就是說:print A
至關於sys.stdout.write(str(A))
。函數
從 2.0版本開始,Python引入了print >>
的語法,做用是重定向print
語句最終輸出字符串的文件。例如,print >> output, A
至關於output.write(str(A) + '\n')
。組件化
若是用Python來實現print函數,它的函數定義應該是這樣的:ui
import sys def print(*objects, sep=None, end=None, file=None, flush=False): """A Python translation of the C code for builtins.print().
""" if sep is None: sep = ' ' if end is None: end = '\n' if file is None: file = sys.stdout file.write(sep.join(map(str, objects)) + end) if flush: file.flush()
從上面的代碼中,咱們能夠發現:Python 3中的print函數實現了print語句的全部特性。spa
print A == print(A) print A, B, C == print(A, B, C) print A, == print(A, end='') print >> output, A == print(A, file=output)
從上面的示例代碼中咱們就能夠看出,使用print函數有明顯的好處:與使用print語句相比,咱們如今可以指定其餘的分隔符(separator)和結束符(end string)。
將print變成函數的真正巧妙之處在與靈活性,但這點並不容易被人發覺。print成爲函數以後,給Python用戶和Python開發團隊帶來了很大的靈活性。對於用戶來講,這可讓你把print
看成表達式(expression)使用;相比之下,print語句就只能做爲語句使用。舉個例子,假設你想在每一行後面打印一個省略號(ellipsis),表示這行還沒有結束。使用print語句的話,你有兩種選擇:
# 手動實現 ... print A, '...' # 可複用的實現(這種方式也適用於print函數) ... def ellipsis_print(*args): for arg in args: print arg, '', print '...'
可是在Python 3中,你能夠選擇更好的解決方式:
# 手動實現 ... print(A, end='...\n') # 多個可複用的解決方案,利用print語句沒法實現... ellipsis_print = lambda *args, **kwargs: print(*args, **kwargs, end='...\n') # 或者 ... import functools ellipsis_print = functools.partial(print, end='...\n')
換句話說,變成函數以後,print
就能夠組件化了,做爲語句的print
是沒法支持的。還有,你還能夠編寫本身喜歡的print
函數,將其賦值給builtins.print
,就能夠覆蓋掉自帶的函數實現了。這一點在Python 2中是不可能實現的。
對於Python開發團隊來講,他們沒必要再從語法層面來實現print
的相關功能了。例如,若是你想讓print
語句也同樣能夠靈活地支持指定分隔符,你要怎樣去實現呢?這會是一個至關難解決的設計難題。可是若是print變成了函數,只須要新增一個參數就解決了。在Python中,函數能夠接受任意數量的參數,這比從底層實現語法帶來的靈活性要大的多。
咱們還要注意,語法實現應該僅限於那些非這樣作不可的功能,或者是以語法形式實現後,大幅提升了可讀性的功能。在print
這個案例中,print A
與print(A)
之間的區別能夠忽略不計,所以並無影響可讀性。並且,因爲咱們可以徹底將print
語句替換爲函數,對於Python語言的功能性也沒有損失。這就是爲何將print
變成函數的緣由。
歡迎你們掃描下方二維碼關注個人公衆號「編程派」,謝謝支持!