国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

聊聊 print 的前世今生

stackvoid / 3354人閱讀

摘要:反對的意見主要是這樣可能會破壞掉無數(shù)個腳本,而且中已經(jīng)有太多的魔法了。除此之外,的命名本身也算是一種包袱。首字母大寫的,譯作史努比,則是一只被很多人喜愛的漫畫小狗。

本文原創(chuàng)并首發(fā)于公眾號【Python貓】,未經(jīng)授權(quán),請勿轉(zhuǎn)載。

原文地址:https://mp.weixin.qq.com/s/Nu...

(一)

上周,我翻譯了一篇文章,解釋了為什么 Python 3 把 print 改為函數(shù)? 概括有如下幾點原因:1、print 不適宜作為應(yīng)用程序級的語句。2、改為一個函數(shù),可以實現(xiàn)更復(fù)雜的功能。3、改為一個函數(shù),能方便地進行替換。

在 Python 2 中,print 是個語句(statement),它的級別就跟 for、if、def 等關(guān)鍵字相同,這是一個古老的設(shè)計(畢竟 Python 誕生于 1989 年),改成 print() 函數(shù),意味著它升級了。

在查閱資料的時候,我發(fā)現(xiàn) print 在歷代版本中,一直發(fā)展變化,到了今天,它自身已足夠完善了,可是外部的挑戰(zhàn)一直不斷。

因此,這篇文章再來聊聊它:介紹 print 的現(xiàn)狀,追溯它的歷史,說說它的挑戰(zhàn)者,挖挖那些更加本質(zhì)的東西。

(二)

在 3.0 版本中,print() 函數(shù)全新登場,開發(fā)者可以自定義打印對象的間隔(默認是空格)、終止方式(默認是換行)、以及輸出位置(默認是標準輸出 sys.stdout)。

而到了 3.3 版本,它還添加了一個新的參數(shù),可以決定是否要刷新數(shù)據(jù)流。

至此,這個函數(shù)的完整格式就變成了 print(*objects, sep=" ", end=" ", file=sys.stdout, flush=False) ,與升級前的 print 語句是天壤之別啦。

優(yōu)點是顯而易見的,可定制的參數(shù)帶來了使用場景的擴充。

(三)

其實,在這次大版本的改動之前,早期的 print 語句并非是一成不變的,核心開發(fā)者們一直在完善它。

例如,在 2000 年的 PEP-214 之前,print 語句只能用于標準輸出(sys.stdout),只有當提出這個提案后,print 才可以打印內(nèi)容到類文件對象(file-like object)中。

(注:PEP 即 Python 改進提案,更多介紹詳見舊文《學(xué)習(xí)Python,怎能不懂點PEP呢?》)

這次調(diào)整后,它的寫法可以如下(其中,mylogfile 是用于記錄打印信息的文件路徑):

print >> mylogfile, "this message goes to my log file"

在只接觸過 Python 3 的同學(xué)眼里,這個寫法可能很別扭吧,其實它等同于如今的:

print("this message goes to my log file", file = mylogfile)

(四)

上例是一次成功的改進,但有趣的是,社區(qū)內(nèi)也有一次失敗的修改提案。

與 print() 函數(shù)相同,print 語句在打印完一個對象后,默認會換行,因此,當打印的內(nèi)容自帶了換行符的時候,最終的打印結(jié)果就會出現(xiàn)一個多余的換行。

2001 年的時候,有開發(fā)者在 PEP-259 中提議,根據(jù)打印的最后一個字符的類型,設(shè)置幾個標志位,以此決定是否要默認換行。校驗規(guī)則如下:

-1 ——如果最后一個對象是以換行符結(jié)束的字符串

0 ——如果最后一個對象是以空白字符結(jié)尾的字符串,既不是空格也不是換行符

1 ——在所有其它情況下(包括最后一個對象是空字符串或不是字符串的情況)

根據(jù)這些規(guī)則,print 語句遇到 -1 標志位的時候,就不再做默認的換行了,似乎可以解決多余換行的問題。

然而,這個提案被否決了。反對的意見主要是:這樣可能會破壞掉無數(shù)個 CGI 腳本,而且 Python 中已經(jīng)有太多的“魔法”了。

這一套規(guī)則確實太神奇了,幸好沒有實施。在當前的版本中,只需調(diào)整 end 參數(shù),就可以避免多余換行的問題。

(五)

閱讀過往的 PEP 文檔,就是在閱讀 Python 的歷史,從中你可以看到設(shè)計者們對功能細節(jié)的打磨過程,最終你就明白了,Python 是如何一步一步地發(fā)展成今天的樣子。

不過,歷史中除了能看到精華,也可以看到一些包袱。print() 函數(shù)的升級就是在甩掉包袱,前不久我寫了《聊聊 Python 的內(nèi)置電池》,聊到了 Python 中廢棄部分標準庫的話題,也是一個很好的觀察例子。

除此之外,“print”的命名本身也算是一種包袱。

早期的計算機使用紙帶作為信息載體,程序的運算結(jié)果需要 print 在紙帶上,所以順理成章地,有些編程語言就使用了“print”來表示程序的輸出操作。盡管后來不再使用紙帶了,一些語言仍然延用這個詞,例如 C 語言以及借鑒了 C 語言的 Python。

Python 的另一個借鑒對象是 Shell,這是一種古老的腳本語言,可它沒有“print”的包袱,它用的是 echo。這個詞的本意是回聲,后來也指雷達的回波,被用于計算機編程中,則又被賦予了“應(yīng)答、回顯”之義,更直白的表述應(yīng)該是“輸出、打印”。

Python 從 C 中借用了“print”命名,又從 Shell 中借用語句式的表達,形成了自己 print 語句,如今到了新的版本,它去除了語句式的表達,卻仍保留著原始命名,可以說這個包袱是永遠脫不掉了。

但是,話說回來,詞語在演化過程中會獲得新的生命,它的意義全在于如何使用。所以,雖然沒有了紙帶這個物理載體,print 這個詞卻“改頭換面”地活了下來。

它還擁有很多的表兄弟姐妹呢,非常熱鬧(試試你能認出幾個?):

print("點個贊吧!")
printf("點個贊吧!");
print_r("點個贊吧!");
var_dump("點個贊吧!");
NSLog(@"點個贊吧!");
System.out.println("點個贊吧!");
console.log("點個贊吧!");
cout?<

(六)

語言內(nèi)部的發(fā)展歷史,以及不同語言的相似表述,都表明著一件事,那就是打印操作很重要,而且我們對它的要求還很復(fù)雜多樣。

Python 中的 print 語句能發(fā)展成今天的 print() 函數(shù),已經(jīng)非常完善了。

不過,需求是無止境的,作為最常用的調(diào)試手段,print() 還達不到十全十美。它的好處是簡單直白、容易上手,但缺點則是功能單一、效率較低,在需要定制格式的頻繁使用場景下,不堪大用。

這在不同編程語言中是通病,因此大家都默契地提供了用于調(diào)試的日志模塊,例如 Java 的 log4j,C++ 的 log4cxx,當然還有 Python 的 logging。

日志模塊 logging 可以說是對 print() 函數(shù)的替代式升級,主要優(yōu)點是更加靈活高效,例如可以設(shè)置不同的日志等級、配置多樣的格式化信息、甚至可以輸出日志到遠程服務(wù)器上。

當然,日志模塊只是一種解決方案,也并不是最完美的。

在 Python 中還有一些模塊可以用于調(diào)試,例如最主流的 pdb,它可以設(shè)置斷點、分步調(diào)試、查看棧片段、動態(tài)調(diào)值等,用得好,有奇效。主流的 IDE 工具也都提供了一些調(diào)試手段,相比于簡單的 print(),它們具有降維打擊的優(yōu)勢。

今年 4 月,Github 上開源了一個專用于調(diào)試程序的庫,名叫 PySnooper ,短短兩個月,它就收獲了近 12K 個關(guān)注。這個三方庫的口號是“Never use print for debugging again”,其目標就是在調(diào)試代碼時完全替代 print。

這個庫的用法非常簡單,只需一行代碼,就可以實現(xiàn)對整個函數(shù)的監(jiān)聽,做到記錄每一行的執(zhí)行時間、記錄每個變量的賦值等等,而且還可以使用“with”語句,監(jiān)聽部分的代碼塊,或者使用“watch”命令,專門監(jiān)聽特定的變量值。

這個庫強大而驚艷,除了上述作用,它還能監(jiān)聽指定格式開頭的代碼,能在多線程中監(jiān)聽線程,甚至支持用戶自定義的監(jiān)聽規(guī)則。難怪它一經(jīng)面世,就好評如潮,人人奔走相告。

snoop 這個單詞很有意思,它指的是嗅探、窺探和監(jiān)聽。首字母大寫的 Snoop ,譯作史努比,則是一只被很多人喜愛的漫畫小狗。所以這個 PySnooper 庫就令我不由地產(chǎn)生了一種聯(lián)想:它是一只嗅覺異常敏銳的小狗,明白無誤地為你執(zhí)行各種監(jiān)聽任務(wù)。

(七)

最后,我們可以來回顧一下 print 的發(fā)展歷史了,有兩條線索,一條是它自身發(fā)展的明線,另一條是它的挑戰(zhàn)者們的暗線。

先看明線吧,早期版本的 print 語句帶有 C 和 Shell 的影子,它是個應(yīng)用程序級的 statement,使用十幾年間,有過一些改進的嘗試,例如 PEP-214 和 PEP-259;到了 2009 年的大版本 3.0,Python 把 print 語句改成了 print() 函數(shù),使它成為了眾多內(nèi)置函數(shù)的一員,隨后在 3.3 版本,又對它做了一次功能增強,至此,它完成了自己的華麗蛻變,占據(jù)了穩(wěn)固的一席之地。

至于暗線,print 的競爭對手們可謂眾多,像傳統(tǒng)的日志模塊 logging、調(diào)試模塊 pdb、以及主流 IDE 的調(diào)試功能,等等,如今還有一位后起之秀 PySnooper,無不瞄準了 print 的位置,摩拳擦掌,虎視眈眈。

print 一詞最早應(yīng)該跟紙帶相關(guān),用途和需求場景都很少,如今的計算機世界已經(jīng)不可同日而語,所以才促進了 print 自身的發(fā)展,也刺激了眾多對手們的崛起。

print 代表了一種訴求/思想:輸出計算結(jié)果、記錄程序過程、監(jiān)察對象變化,然后用于查看、分析、調(diào)試、展示等等。

明線上的發(fā)展,就是繼承了它的名字,壯大 print;暗線上的發(fā)展,則是繼承了它的思想,為了實現(xiàn)目的,各施手段,百花齊放。

print 當然不是 Python 所特有的,這明暗兩線的發(fā)展也同理,如果你把視野放到任何一個經(jīng)得起時間考驗的語言上,必然也會看到相似的發(fā)展歷程與競爭故事。

最后,如果你想了解更多內(nèi)容,可通過以下鏈接查看:

https://docs.python.org/3/library/functions.html#print

學(xué)習(xí)Python,怎能不懂點PEP呢?

https://www.python.org/dev/peps/pep-0214/

https://www.python.org/dev/peps/pep-0259/

為什么 Python 3 把 print 改為函數(shù)?

https://github.com/cool-RR/PySnooper

公眾號【Python貓】, 本號連載優(yōu)質(zhì)的系列文章,有喵星哲學(xué)貓系列、Python進階系列、好書推薦系列、技術(shù)寫作、優(yōu)質(zhì)英文推薦與翻譯等等,歡迎關(guān)注哦。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/44104.html

相關(guān)文章

  • GPU前世今生

    摘要:的主要競爭對手,不僅是獨立顯卡的經(jīng)銷商,也是的經(jīng)銷商,盡管在端各方面遜于,但是在游戲主機包括等,均由提供供應(yīng)。 提起GPU,電腦端的游戲玩家一定不會陌生,這個橫在自己和3A游戲間最大的障礙,讓多少玩家欲哭無淚;而搞設(shè)計的朋友在面對漫長的渲染等待時,也恨不得手動給GPU提提速。那么GPU到底是什么?今天的文章我們來聊聊它的前世今生。showImg(https://segmentfault...

    Guakin_Huang 評論0 收藏0
  • python協(xié)程前世今生

    摘要:協(xié)程的歷史說來話長,要從生成器開始講起。我們可以使用把數(shù)據(jù)發(fā)送給協(xié)程函數(shù)。可以看到,在第次接收完數(shù)據(jù)之后,會產(chǎn)生結(jié)束的異常,因為程序流程結(jié)束了,這是正常現(xiàn)象。在這個階段,協(xié)程本質(zhì)上還是由生成器構(gòu)成的。所以,協(xié)程的介紹到這里就結(jié)束啦。 在上一篇對python并發(fā)編程的理解 中,我簡單提到了協(xié)程的概念,有一個錯誤需要指出的是,asyncio不全是對協(xié)程的實現(xiàn),只是用到了協(xié)程。 協(xié)程的歷史說...

    stackfing 評論0 收藏0
  • Web技術(shù)前世今生(二)

    摘要:前言我是,如果你還不認識我,不妨先看看技術(shù)的前世今生一平靜的生活已經(jīng)有一段日子了。傳送門技術(shù)的前世今生一技術(shù)的前世今生三 前言:我是JavaScript,如果你還不認識我,不妨先看看《Web技術(shù)的前世今生(一)》 平靜的生活已經(jīng)有一段日子了。 這一天,HTML大哥面露不悅地走過來問我: Js,你是打算和我們分家嗎? 大哥,您這說的哪里話,我什么地方做的不對么?我一臉茫然地回答道。 哼,...

    Stardustsky 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<