日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
不要使用Python開(kāi)發(fā)大型項(xiàng)目!

審校 | 千山

創(chuàng)新互聯(lián)執(zhí)著的堅(jiān)持網(wǎng)站建設(shè),小程序定制開(kāi)發(fā);我們不會(huì)轉(zhuǎn)行,已經(jīng)持續(xù)穩(wěn)定運(yùn)營(yíng)十載。專業(yè)的技術(shù),豐富的成功經(jīng)驗(yàn)和創(chuàng)作思維,提供一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造品牌,攜手廣大客戶,共同發(fā)展進(jìn)步。

本文將通過(guò)對(duì)變量聲明、模塊歸屬、依賴沖突、包管理、全局解釋器鎖以及并發(fā)和并行計(jì)算等方面的分析,向你解釋為什么不推薦在開(kāi)發(fā)大型項(xiàng)目時(shí)使用Python。

  Python并非你想象中那么棒!

在開(kāi)發(fā)人員的職業(yè)生涯中,有一個(gè)特定的階段,即從為項(xiàng)目做出貢獻(xiàn)到發(fā)明自己的技術(shù)。對(duì)一些人來(lái)說(shuō)這個(gè)階段會(huì)來(lái)得更早一些,對(duì)另一些人來(lái)說(shuō)則可能更晚,而有些人根本就沒(méi)有這個(gè)階段。大多數(shù)職業(yè)生涯較長(zhǎng)的開(kāi)發(fā)人員都經(jīng)歷過(guò)這一點(diǎn),我稱之為“自己動(dòng)手建造”階段。

如果你是一位職業(yè)生涯較長(zhǎng)的開(kāi)發(fā)人員,那么你應(yīng)該知道本小節(jié)標(biāo)題的真正含義:它是如何工作的?用戶體驗(yàn)如何?應(yīng)用框架是什么?數(shù)據(jù)是如何流動(dòng)的?還有更多類似的問(wèn)題。

我不會(huì)在這里為你回答所有這些問(wèn)題。針對(duì)你要開(kāi)始的任何項(xiàng)目,它們都是一些非常具體的問(wèn)題。這些問(wèn)題中的每一個(gè)都值得至少使用一篇文章來(lái)加以解釋。

不過(guò),我還是樂(lè)意回答一個(gè)問(wèn)題:哪種語(yǔ)言最適合項(xiàng)目開(kāi)發(fā)?

你可能會(huì)認(rèn)為這也是因項(xiàng)目而異的非常具體的問(wèn)題。的確,你并沒(méi)有完全錯(cuò)。但每種編程語(yǔ)言都有一些缺陷。事實(shí)證明,Python也存在很多陷阱。尤其是當(dāng)你試圖用它來(lái)構(gòu)建一個(gè)大型程序時(shí)。

  變量不聲明導(dǎo)致的問(wèn)題

Python禪宗(Zen of Python)的建議是:顯式優(yōu)于隱式。然而,在實(shí)際Python開(kāi)發(fā)中,隱式聲明比顯式聲明更常見(jiàn)。

與此相反,大家不妨考慮下面這樣一小段C代碼:

char notpython[50] = "This isn't Python.";

在我們回到Python話題前,先讓我們深入了解一下上面這段C代碼。

在此,char是一個(gè)類型標(biāo)識(shí)符,它告訴你后面的所有內(nèi)容都與字符串有關(guān)?!皀otpython”是我給這個(gè)字符串起的名字。[50]告訴你,C將為此保留50個(gè)字符的內(nèi)存空間。不過(guò),在本例中,我可以得到19個(gè)字符——每個(gè)字符對(duì)應(yīng)一個(gè)空間位置,最后加上一個(gè)空字符\0。最后,用分號(hào)簡(jiǎn)潔地結(jié)束。

這種顯式聲明在C語(yǔ)言中是必須的。如果省略顯式聲明,編譯器將出現(xiàn)相應(yīng)錯(cuò)誤提示!這種做事方式一開(kāi)始似乎既愚蠢又乏味,但卻是非常值得的。

當(dāng)你在兩周或兩年后閱讀C代碼時(shí),例如你偶然發(fā)現(xiàn)了一個(gè)你不知道的變量,你只需檢查一下它的聲明。當(dāng)然,如果你給它起了一個(gè)有意義的名字,那么這會(huì)提供給你一個(gè)強(qiáng)有力的線索:有關(guān)它是什么,它在做什么,它需要在哪里,等等。

現(xiàn)在,讓我們將其與Python進(jìn)行比較。

在Python中,你幾乎可以一邊編寫(xiě)代碼一邊聲明新的變量。不過(guò),如果你沒(méi)有給它起一個(gè)有意義的名字或者至少留下一條注釋的話,那么過(guò)些時(shí)候再閱讀此代碼時(shí)你會(huì)覺(jué)得問(wèn)題變得一團(tuán)糟。

在Python中,除了深入分析有關(guān)源代碼之外,你根本無(wú)法理解變量在做什么。

但是如果你在一個(gè)變量中有一個(gè)輸入錯(cuò)誤,那么就可能破壞你的整個(gè)代碼,因?yàn)椴淮嬖谙馛中那樣的保護(hù)聲明。

如果你在做更小的項(xiàng)目,比如說(shuō)幾千行的代碼,那就沒(méi)關(guān)系;或者如果你的項(xiàng)目不是很復(fù)雜時(shí),也會(huì)存在什么問(wèn)題。但是當(dāng)有了更大的項(xiàng)目時(shí),就會(huì)遇到極大麻煩。

是的,你可以在Python中進(jìn)行顯式變量聲明。但事實(shí)上,只有最勤奮的程序員才能做到這一點(diǎn)。更實(shí)際的情形是:當(dāng)編譯器沒(méi)有“抱怨”時(shí),許多人會(huì)完全忘記這些額外的代碼行。

編寫(xiě)Python代碼是很快速的事情,而且對(duì)于小型和簡(jiǎn)單的項(xiàng)目來(lái)說(shuō),閱讀Python也很容易。

然而,在閱讀和維護(hù)大型Python項(xiàng)目時(shí),例如當(dāng)尋找描述性變量名和注釋所有代碼方面,你最好是世界級(jí)程序員,否則你就完蛋了。

  模塊歸屬問(wèn)題

如果你認(rèn)為事情不會(huì)變得更糟,那你就錯(cuò)了。

變量在代碼中從何處開(kāi)始“存在”的問(wèn)題不僅僅源于隱式聲明。

變量也可能來(lái)自其他模塊。它們的形式通常像my_module.my_variable()。如果你對(duì)這樣一個(gè)變量感到困惑,那么當(dāng)你檢查了它在主文件中的其他位置時(shí),你還沒(méi)有徹底解決問(wèn)題。

你還需要檢查是否存在一行代碼,像下面其中之一:

import my_module

from another_module import my_module

在第二行代碼中,你告訴編譯器你需要從一個(gè)包含更多內(nèi)容的模塊中得到哪個(gè)函數(shù)或變量。

這是很煩人的事情,因?yàn)槟阍赑yPI(https://pypi.org/)上能找到更多的模塊,而且你還可以在計(jì)算機(jī)上導(dǎo)入任何其他Python文件。所以,快速搜索函數(shù)或變量并不總是有效。

但有些情況下,問(wèn)題可能會(huì)變得更加糟糕。例如,有的模塊可能依賴于其他模塊。如果你運(yùn)氣不好,例如你導(dǎo)入了模塊A、B和C,但它們又依賴于模塊E、F、G和H,而模塊E、F、G和H又依賴于I、J和K。突然之間,你需要管理的模塊不是三個(gè),而變成了十個(gè)!

更糟糕的是,有時(shí)這種依賴并不是一棵簡(jiǎn)單的依賴樹(shù)。假設(shè)B和C也依賴于M和N,J也依賴于M,C和H也依賴于Q……不必再?gòu)?qiáng)調(diào),你應(yīng)該明白了一切。

這就像一個(gè)迷宮一樣。Python程序員把此稱為“依賴地獄”——的確是真實(shí)存在的。

而循環(huán)依賴算是迷宮中“最丑陋的野獸”。例如,如果模塊A依賴于模塊B,但模塊B也使用模塊A的一部分時(shí)——你的麻煩大了!

對(duì)于小項(xiàng)目來(lái)說(shuō),這沒(méi)什么大不了的。但對(duì)于大的項(xiàng)目……你可能會(huì)一頭扎進(jìn)“原始叢林”。

  大規(guī)模的依賴沖突

我還沒(méi)發(fā)泄完我對(duì)模塊的咆哮:不僅是模塊本身,還有它們的版本方面也存在問(wèn)題。

原則上,Python擁有如此活躍的用戶群,并且許多模塊都定期更新,這是非常棒的。然而,只有一個(gè)問(wèn)題:并非所有版本的模塊都與其他模塊兼容。

例如,假設(shè)你正在使用模塊A和B。這兩個(gè)模塊都依賴于模塊C。但是A在3.2或更高版本中需要C,而B(niǎo)在2.9或更低版本中需要C。你不在乎C,你只想要A和B。

世界上沒(méi)有任何工具能幫你解決這場(chǎng)沖突。如果幸運(yùn)的話,你會(huì)發(fā)現(xiàn)一個(gè)補(bǔ)丁,它是由與你遇到同樣問(wèn)題的人編寫(xiě)的。如果你沒(méi)那么幸運(yùn),你就得自己寫(xiě)補(bǔ)丁了。

或者使用不同的軟件包。或者完全重寫(xiě)其中一個(gè)包A或B,然后在需要錯(cuò)誤版本的C的任何地方找到解決方法。

總之,在任何情況下,你都需要花費(fèi)額外的時(shí)間。

這是一片“代碼叢林”,你需要耐心和一些工具來(lái)駕馭它才行。

撇開(kāi)依賴沖突不談,還有一些不錯(cuò)的工具。例如,有一個(gè)名為pip的工具,可以使安裝軟件包變得容易。借助一個(gè)簡(jiǎn)單的文本文件“requirements.txt”,你可以指定要使用的軟件包和版本,而不是弄亂文件頭部。虛擬環(huán)境將所有軟件包放在一個(gè)地方,并與主要的Python安裝分開(kāi)。

對(duì)于更大、更混亂的項(xiàng)目,還可以借助conda、YAML文件等途徑來(lái)解決上述問(wèn)題。

但無(wú)論如何,你都需要學(xué)習(xí)如何使用每種工具。而且,你需要花最少的時(shí)間來(lái)處理這些問(wèn)題。

  不同機(jī)器上的Python問(wèn)題

與上述“依賴地獄”世界聯(lián)系在一起的是另一個(gè)令人不安的話題。

即使你已經(jīng)解決了機(jī)器上的所有依賴性問(wèn)題,并且Python像一匹新生的馬一樣平穩(wěn)運(yùn)行,也不能保證它會(huì)在其他人的機(jī)器上正常運(yùn)行。

新生的馬會(huì)跑嗎?我不知道,但我似乎在努力讓自己在生物學(xué)方面比以往任何時(shí)候都更有學(xué)識(shí)。閑言少敘,讓我們回到Python話題。

像pip、文本文件requirements.txt和虛擬環(huán)境這樣的工具將有助于你在一定程度上克服依賴地獄問(wèn)題。但是,這種便利僅限于本地情形。

在每臺(tái)新機(jī)器上,你都需要檢查并可能重新安裝每個(gè)需求及其版本。

唯一真正便攜的解決方案是借助Jupyter notebooks。在這里你可以用任何你喜歡的版本寫(xiě)東西。在Jupyter中,所有內(nèi)容都通過(guò)在線服務(wù)器運(yùn)行,因此你可以將這些文件發(fā)送給任何人,他們的確能夠“開(kāi)箱即用”。

不過(guò),這種方法也存在一個(gè)明顯的缺點(diǎn):Jupyter notebooks只有圖形界面,而有時(shí)候僅僅使用圖形界面,很難處理包含許多相互關(guān)聯(lián)文件的大型項(xiàng)目。

也許這就是為什么我從未在Jupyter notebooks上看到過(guò)大型項(xiàng)目,盡管它們確實(shí)存在。

相比之下,其他一些計(jì)算機(jī)語(yǔ)言只使用虛擬機(jī),這類問(wèn)題即可迎刃而解。

  除Pip之外的工具

假設(shè)你已經(jīng)通過(guò)使用Jython或PyPy或類似的解決方案將項(xiàng)目移植到不同的機(jī)器上。所有這些操作都比虛擬機(jī)稍顯笨拙。但是,至少它們能夠正常工作了!

如果你正在組建一個(gè)大項(xiàng)目,你可能會(huì)集成C包、Fortran包等等。這樣做有很多好處:Python中可能不存在C包,而且通常速度更快。出于歷史原因,科學(xué)計(jì)算類軟件包通常只存在于Fortran中。

實(shí)際上,您將不得不使用諸如gcc、gfortran之類的編譯器,或許還有其他更多的編譯器。

這太麻煩了!在Python代碼中集成C模塊的文檔超過(guò)4500字——是本文的兩倍!Fortran相關(guān)的文檔也沒(méi)有那么短。

用C語(yǔ)言構(gòu)建整個(gè)項(xiàng)目最初可能會(huì)耗費(fèi)更長(zhǎng)時(shí)間;但是,你可以防止出現(xiàn)必須處理多個(gè)編譯器和接口的情況。

C是如此古老的語(yǔ)言,以致幾乎任何東西都有對(duì)應(yīng)的C語(yǔ)言包裝版本,甚至包括用戶友好的機(jī)器學(xué)習(xí)軟件包。

  使用全局解釋器鎖鎖定性能

全局解釋器鎖(GIL)從Python誕生的第一天起就一直存在,它能夠使終端用戶的內(nèi)存管理變得非常簡(jiǎn)單。

至少在較小的項(xiàng)目中,開(kāi)發(fā)人員在使用Python時(shí)根本不需要考慮計(jì)算機(jī)內(nèi)存問(wèn)題。我們不妨將其與C語(yǔ)言比較一下:在C語(yǔ)言中,需要為每個(gè)變量保留一些內(nèi)存。

基本上,GIL能夠自動(dòng)計(jì)算一個(gè)變量在代碼的每個(gè)部分中被引用的次數(shù)。如果不再需要該變量,GIL就會(huì)釋放它所占用的內(nèi)存空間。

在小型項(xiàng)目中,GIL有助于提高性能,因?yàn)椴槐匾膬?nèi)存空間會(huì)被及時(shí)清除掉。

但在更大的項(xiàng)目中有一個(gè)問(wèn)題:GIL不喜歡多線程!

當(dāng)多個(gè)指令線程在同一進(jìn)程資源上獨(dú)立運(yùn)行時(shí),這是一種高性能執(zhí)行程序的方法。機(jī)器學(xué)習(xí)模型很適合這樣訓(xùn)練。

然而,只有一個(gè)小問(wèn)題:GIL一次只能在一個(gè)線程上工作。

于是,會(huì)出現(xiàn)這樣的情況:例如變量A在線程1上執(zhí)行,而線程2已經(jīng)用完了變量A,那么它的內(nèi)存可能最終會(huì)被刪除。這種情況取決于GIL當(dāng)時(shí)在哪里運(yùn)行。

因此,這可能會(huì)導(dǎo)致非常奇怪的錯(cuò)誤,正如你所想象的……

這方面有一些變通辦法,但都不是很漂亮。另一種選擇方案是借助于多進(jìn)程來(lái)完成計(jì)算。但在沒(méi)有GIL的語(yǔ)言中,它通常不會(huì)像多線程那樣快。

  并發(fā)和并行計(jì)算依然讓人頭疼

我們已經(jīng)看到了并發(fā)的一個(gè)缺點(diǎn)。在進(jìn)行多線程處理時(shí),全局解釋器鎖會(huì)降低速度,或者導(dǎo)致奇怪的錯(cuò)誤。

同樣的缺點(diǎn)也存在于Python的協(xié)程中。

線程和協(xié)程之間有一些細(xì)微的區(qū)別,但最重要的一點(diǎn)是:協(xié)程一次執(zhí)行一個(gè)任務(wù),而線程可以同時(shí)執(zhí)行多個(gè)任務(wù),二者都是并發(fā)實(shí)現(xiàn)的。

當(dāng)你有需要大量等待的任務(wù)時(shí),協(xié)程非常有用,例如當(dāng)你正在閱讀網(wǎng)站數(shù)據(jù)并等待服務(wù)器響應(yīng)時(shí)的情形。協(xié)程不會(huì)讓計(jì)算機(jī)無(wú)所事事,而是給它分配另一項(xiàng)任務(wù)。

另一方面,當(dāng)你有幾個(gè)任務(wù)很耗時(shí)但不需要太多CPU消耗,也不需要太多等待時(shí),線程是很有用的。流式數(shù)據(jù)就是一個(gè)例子。

如果你有一個(gè)CPU密集型任務(wù),并且你想充分利用你的硬件,你可能想嘗試一下使用并行計(jì)算。

多進(jìn)程會(huì)成為你最好的朋友——它基本上是告訴計(jì)算機(jī)使用多個(gè)內(nèi)核進(jìn)行計(jì)算,從而節(jié)省大量時(shí)間。

不過(guò),線程、協(xié)同程序和多進(jìn)程這三種技術(shù)都面臨類似的問(wèn)題。它們?cè)赑ython中實(shí)現(xiàn)起來(lái)并不難。但是代碼看起來(lái)很笨重,很難閱讀,尤其是對(duì)于初學(xué)者來(lái)說(shuō)。

相比來(lái)說(shuō),Clojure、Go和Haskell等語(yǔ)言在并發(fā)性和并行性方面性能要好得多。但是,如果你不是在處理緩慢或密集的進(jìn)程,那么你根本不必考慮這樣的方案。但如果當(dāng)你遇到這樣的問(wèn)題時(shí),那么你可能需要考慮選擇語(yǔ)言的問(wèn)題了。

  用哪一種語(yǔ)言代替Python?

Python并不全是邪惡的,但它的確也存在缺點(diǎn)。

因此,如果你想要明確說(shuō)明的變量和開(kāi)發(fā)良好的包,而這些包不會(huì)讓你輕易陷入依賴地獄,那么你可以選擇C語(yǔ)言。此外,如果你想要任何機(jī)器都可以移植的東西,那么Java、Clojure或Scala都是不錯(cuò)的選擇。因?yàn)樗鼈冊(cè)谔摂M機(jī)上運(yùn)行,所以你不會(huì)遇到與Python相同的問(wèn)題。

還有,如果你想執(zhí)行大而慢的任務(wù),你可能想試試Go或Haskell。盡管一開(kāi)始,它們比Python更難學(xué)習(xí),但你投入的時(shí)間是有回報(bào)的。特別是,你總可以把多種語(yǔ)言組合起來(lái)使用。

Python非常適合快速編寫(xiě)腳本、初稿,甚至適合中等規(guī)模的項(xiàng)目。我認(rèn)識(shí)的許多開(kāi)發(fā)人員都用Python編寫(xiě)初稿和測(cè)試運(yùn)行,然后再使用C、Go或Clojure重寫(xiě)重要的部分。這使代碼執(zhí)行更快,而且你仍然可以享受Python提供的優(yōu)勢(shì)。

在大型項(xiàng)目中,Python并不是被禁止使用,只不過(guò)這可能不是唯一使用的語(yǔ)言而已。你可以通過(guò)Python像膠水一樣將C、Go或Clojure中的代碼拼接在一起。此外,如果你已經(jīng)達(dá)到了自己構(gòu)建的階段,那么請(qǐng)記?。簺](méi)有任何一種語(yǔ)言是絕對(duì)優(yōu)秀的!

總之,盡管Python有缺點(diǎn),但它的確很酷,而且也很方便。通過(guò)使用Python集成其他語(yǔ)言中的代碼,你總是可以繞過(guò)有關(guān)難點(diǎn)并最終解決問(wèn)題。

譯者介紹

朱先忠,社區(qū)編輯,專家博客、講師,濰坊一所高校計(jì)算機(jī)教師,自由編程界老兵一枚。早期專注各種微軟技術(shù)(編著成ASP.NET AJX、Cocos 2d-X相關(guān)三本技術(shù)圖書(shū)),近十多年投身于開(kāi)源世界(熟悉流行全棧Web開(kāi)發(fā)技術(shù)),了解基于OneNet/AliOS+Arduino/ESP32/樹(shù)莓派等物聯(lián)網(wǎng)開(kāi)發(fā)技術(shù)Scala+Hadoop+Spark+Flink等大數(shù)據(jù)開(kāi)發(fā)技術(shù)。


當(dāng)前名稱:不要使用Python開(kāi)發(fā)大型項(xiàng)目!
文章地址:http://www.5511xx.com/article/cdgeeei.html