作為一個(gè)數(shù)年C/Java/Python混合開發(fā)者, 我談?wù)勎业母惺?
我認(rèn)為C, Java跟Python都是非常成功的語(yǔ)言, 具體選哪種看你的場(chǎng)景.
言歸正傳,來(lái)對(duì)比一個(gè)Python跟Java.
Python:
優(yōu)點(diǎn) ( 知乎怎么不能把這行字變大點(diǎn)??):
語(yǔ)法簡(jiǎn)潔優(yōu)美, 功能強(qiáng)大, 標(biāo)準(zhǔn)庫(kù)跟第三方庫(kù)灰常強(qiáng)大, 應(yīng)用領(lǐng)域非常廣: vinta/awesome-python · GitHub(跟PHP形成宣明對(duì)比!)
語(yǔ)言方面, 舉幾個(gè)例子:
一切都是對(duì)象!!!
類(class本身)/函數(shù)/類方法是callable的對(duì)象
List表達(dá)式(其他好多語(yǔ)言也有,但是我喜歡python的寫法):
把"1023"變成 [1, 2, 3]
[ int(x) for x in "1023" if x != "0" ]
(當(dāng)前你可以用Lisp風(fēng)格的: map(int, filter(lambda x: x != "0", "1024")))
對(duì)dict也是類似:
adict = {"a":1, "b":2}
{k: v*2 for k, v in adict.items() }
yield關(guān)鍵字:
當(dāng)你需要返回很多東西然后一個(gè)一個(gè)用的時(shí)候, 你可以一次返回一個(gè)
def xrange(n):
i = 0
while i < n:
yield i
i += 1
用法:
for i in xrange(10):
print i
裝飾器@:
把something_heavy()返回的結(jié)果緩存起來(lái)(以函數(shù)名+args為緩存的鍵值,只緩存近使用的10條)
@functool.lru_cache(10)
def something_heavy(args):
#各種耗時(shí)操作.....
pass
運(yùn)算符重載:
試試numpy, 你會(huì)驚呆的, 操作向量/矩陣跟基本類型一樣方便
缺點(diǎn):
慢
目測(cè)python是慢的腳本語(yǔ)言,比V8上的JS還慢不少. (研究一下描述符,你會(huì)發(fā)現(xiàn)python調(diào)用對(duì)象方法的開銷好大!)
但是python創(chuàng)始人說(shuō)了, 一般程序的瓶頸在于20%的代碼, 所以你可以把那20%的代碼用C重寫(而python是膠水語(yǔ)言,用C重寫部分代碼當(dāng)然很easy啦)
同時(shí),你可以試試PyPy, 引入了JIT技術(shù)
動(dòng)態(tài)類型
有人說(shuō): 動(dòng)態(tài)類型寫時(shí)爽, 重構(gòu)起來(lái)是災(zāi)難(原諒我記不得原話..).
對(duì)于不寫unittest, 不做代碼覆蓋率測(cè)試的人來(lái)說(shuō), 動(dòng)態(tài)語(yǔ)言當(dāng)然是危險(xiǎn)的, 拼寫錯(cuò)誤都可能被隱藏, 重構(gòu)?別搗亂!
python創(chuàng)始人有話說(shuō): "如果你認(rèn)為編譯器可以幫你解決所有問(wèn)題,那你一定干編程沒(méi)多久" (鄙人深有體會(huì),曾經(jīng)年少輕狂的我非常鄙視javascript), "不管什么程序,都需要寫testcase, 既然要寫testcase, 那么動(dòng)態(tài)類型不是問(wèn)題!"
在此推薦大家兩個(gè)工具: py.test python-coverage
Java:
優(yōu)點(diǎn)
用幾個(gè)詞形容一下Java語(yǔ)言: 優(yōu)美, 嚴(yán)謹(jǐn), 健壯,不易出錯(cuò).
當(dāng)然, 使用也非常的廣泛: 常年盤踞編程人員數(shù)量排行榜名!
各種庫(kù)也灰常多: akullpp/awesome-java · GitHub
同樣的代碼, 相比C++(甚至python), Java代碼出BUG的概率要小點(diǎn)(當(dāng)然,寫的時(shí)候一般會(huì)比python長(zhǎng)).
Java從語(yǔ)言設(shè)計(jì)上盡量避免了程序員犯錯(cuò), 比如自動(dòng)垃圾回收, 拋棄無(wú)符號(hào)類型, 安全的枚舉, 編譯期泛型檢查(Java1.5之后加入的泛型,但是只是用來(lái)做編譯器檢查,運(yùn)行時(shí)跟以前一樣), 強(qiáng)制的異常處理(遇到異常必須catch或者申明throws) 等等(當(dāng)然,某些特性python也有.)
Java標(biāo)準(zhǔn)庫(kù)和好多第三方代碼都充斥著濃濃的設(shè)計(jì)感!!!, 各種設(shè)計(jì)模式到處可見. 從下面的語(yǔ)句可以看出一點(diǎn)來(lái):
new BufferedInputStream(new FileInputStream(new File("somepath")))
尼瑪, 好多字, 看我的:
C:
fopen("somepath", "r")
Python:
open("somepath")
Java代碼多,但是API可復(fù)用行強(qiáng),選擇多(我想一次讀完文件,不要buffer呢?)
因?yàn)榻寻踩?所以Java成了企業(yè)級(jí)后臺(tái)的標(biāo)準(zhǔn). 想想銀行后臺(tái), 關(guān)鍵地方出點(diǎn)bug可不得了
掃碼匿名提建議
直達(dá)CEO信箱