摘要:忽略了的版本這是一個(gè)在上不斷被人提起的問(wèn)題。不幸的是它只運(yùn)行在系統(tǒng)上。誤解了全局解釋器鎖意味著只有一個(gè)線程在一個(gè)程序可以運(yùn)行在任何時(shí)間。規(guī)定的解決方案是使用模塊。濫用使得上的一個(gè)大神花了很多時(shí)間去解決它。這可能會(huì)產(chǎn)生一些非常不必要的后果。
原文鏈接放在這里:1: http://nafiulis.me/potential-pythonic-pitfalls.html
很多問(wèn)題沒(méi)搞懂,先放在這里,慢慢改。
python是一門(mén)非常有趣的語(yǔ)言。它提供了許多非常方便的標(biāo)準(zhǔn)庫(kù)和許多內(nèi)置命令是我們輕松完成任務(wù).但是好東西太多了就有選擇恐懼癥了,以至于我們不能很好第利用這個(gè)標(biāo)準(zhǔn)庫(kù)和它的基本機(jī)構(gòu)。下面列出了一些對(duì)python新手來(lái)說(shuō)很簡(jiǎn)單有效的陷阱。
這是一個(gè)在StackOverflow上不斷被人提起的問(wèn)題。當(dāng)你完美的代碼跑在別人的電腦上就報(bào)錯(cuò)是怎樣一種體驗(yàn),所以這個(gè)時(shí)候就需要檢查你們的python版本是否一致。確保代碼跑在自己知道的python版本上。你可以通過(guò)以下代碼查看python版本:
$ python --version Python 2.7.9python版本管理
pyenv是一個(gè)不錯(cuò)的python版本管理工具。不幸的是它只運(yùn)行在*nix系統(tǒng)上。在Mac OS上,你可以簡(jiǎn)單用brew install pyenv安裝,在linux系統(tǒng)中,有一個(gè)自動(dòng)安裝器automatic installer
糾結(jié)于用一行代碼解決所有問(wèn)題許多人夸口說(shuō)我多牛用一行代碼就解決了所有問(wèn)題,即便他們的代碼比正常寫(xiě)的更缺少效率,而且這些代碼也會(huì)更難以閱讀,甚至?xí)霈F(xiàn)歧義。比如說(shuō):
l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]
老實(shí)說(shuō)上面的代碼是我自己為了說(shuō)明這件事情寫(xiě)的。但是我可是真的見(jiàn)過(guò)有許多人這樣干過(guò)。如果你只是簡(jiǎn)單通過(guò)把東西添加到一個(gè)list或者一個(gè)set中來(lái)顯擺自己解決復(fù)雜問(wèn)題的手段,那么你有可能會(huì)得不償失。
一行代碼控并不是什么巨大的成就,盡管有時(shí)候看起來(lái)特別聰明。優(yōu)秀的代碼是簡(jiǎn)潔但是更注重高效和易讀。
錯(cuò)誤地初始化set這是一個(gè)更加微妙的問(wèn)題,有時(shí)候會(huì)讓你措手不及。set推導(dǎo)式起來(lái)有點(diǎn)像list推導(dǎo)式.
>>> { n for n in range(10) if n % 2 == 0 } {0, 8, 2, 4, 6} >>> type({ n for n in range(10) if n % 2 == 0 })
上面的例子說(shuō)明了這點(diǎn)。set有點(diǎn)像放在容器中的list
它們的區(qū)別是set沒(méi)有重復(fù)的值和無(wú)序的。人們通常會(huì)把{}認(rèn)為是一個(gè)空的set,可它不是,它是一個(gè)空的dict.
>>> {} {} >>> type({})
所以如果我們想要初始化一個(gè)空的set,就直接使用set()
>>> set() set() >>> type(set())
注意一個(gè)空的set可以表示成set(),但是一個(gè)包含了元素的集合要被定義成set([1, 2])的樣子。
GIL(全局解釋器鎖)意味著只有一個(gè)線程在一個(gè)Python程序可以運(yùn)行在任何時(shí)間。 這意味著當(dāng)我們不能創(chuàng)建一個(gè)線程,并期望它并行運(yùn)行。 Python解釋器實(shí)際上做的是快速切換不同的運(yùn)行線程。 但這是一個(gè)非常簡(jiǎn)單的版本。 在許多實(shí)例中程序并行運(yùn)行,像使用C擴(kuò)展的庫(kù)時(shí)。 但Python代碼運(yùn)行時(shí),大多數(shù)時(shí)候不會(huì)并行執(zhí)行。換句話說(shuō),線程在Python中不像在Java或c++中一樣。
許多人會(huì)嘗試為Python辯解說(shuō),這些都是真正的線程。 3 這確實(shí)是真的,但并不能改變這樣一個(gè)事實(shí):Python處理線程的方式不同于你期望的那樣。 Ruby也有類(lèi)似的情況(還有一個(gè)解釋器鎖)。
規(guī)定的解決方案是使用multiprocessing模塊。multiprocessing模塊提供的過(guò)程類(lèi)基本上可以很好地覆蓋分歧。 然而,分歧比線程代價(jià)高得多。所以并行運(yùn)行不總是好的。
然而,這個(gè)問(wèn)題不是每個(gè)Python程序都會(huì)遇到。PyPy-stm就是Python的一個(gè)實(shí)現(xiàn)不受GIL影響的例子。 實(shí)現(xiàn)建立在其他平臺(tái)上的像JVM(Jython) 或CLR(IronPython)沒(méi)有GIL的問(wèn)題。
總之,在使用時(shí)要小心線程類(lèi),你得到的可能不是你想要的。
使用過(guò)時(shí)的樣式類(lèi)在Python 2有兩種類(lèi)型的類(lèi),“舊式”類(lèi),“新風(fēng)格”類(lèi)。 如果 你使用Python 3,那么你正在使用默認(rèn)的“新風(fēng)格”類(lèi)。 為了確保你使用 “新風(fēng)格”在Python 2類(lèi),您需要繼承object或者任何你創(chuàng)建的不總是繼承內(nèi)建指令int或list的新類(lèi) 。 換句話說(shuō),你的基類(lèi),應(yīng)該總是繼承object。
class MyNewObject(object): # stuff here
這些"新類(lèi)"修復(fù)了一些非?;镜某霈F(xiàn)在老式類(lèi)中問(wèn)題,如果你感興趣可以查看文檔
錯(cuò)誤的迭代下面的這些錯(cuò)誤對(duì)新手來(lái)說(shuō)非常常見(jiàn):
for name_index in range(len(names)): print(names[name_index])
很明顯沒(méi)有必要使用len, 實(shí)際上遍歷列表用非常簡(jiǎn)單的語(yǔ)句就可以實(shí)現(xiàn):
for name in names: print(name)
此外,還有一大堆其他的工具在你處理簡(jiǎn)化迭代。 例如,zip可以用來(lái)遍歷兩個(gè)列表:
for cat, dog in zip(cats, dogs): print(cat, dog)
如果我們要考慮索引和值列表變量,我們可以使用enumerate
for index, cat in enumerate(cats): print(cat, index)
在itertools中還有很多功能可以選擇。如果itertools中有你想要的功能就很方便的拿來(lái)用。但是也不要過(guò)于為了用它而用它。
itertools濫用使得StackOverflow上的一個(gè)大神花了很多時(shí)間去解決它。
使用了可變的默認(rèn)參數(shù)我看過(guò)很多如下:
def foo(a, b, c=[]): # append to c # do some more stuff
不要使用可變的默認(rèn)參數(shù),而不是使用以下:
def foo(a, b, c=None): if c is None: c = [] # append to c # do some more stuff
下面這個(gè)例子可以很直觀地幫我們理解這個(gè)問(wèn)題:
In[2]: def foo(a, b, c=[]): ... c.append(a) ... c.append(b) ... print(c) ... In[3]: foo(1, 1) [1, 1] In[4]: foo(1, 1) [1, 1, 1, 1] In[5]: foo(1, 1) [1, 1, 1, 1, 1, 1]
相同的 c 被引用一次又一次的每一次調(diào)用該函數(shù)。 這可能會(huì)產(chǎn)生一些非常 不必要的后果。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37543.html
摘要:與純占位符相對(duì)應(yīng),非純占位符的切片是非空列表,對(duì)它進(jìn)行操作賦值與刪除,將會(huì)影響原始列表。不同位置的替換非等長(zhǎng)替換刪除元素切片占位符可以帶步長(zhǎng),從而實(shí)現(xiàn)連續(xù)跨越性的替換或刪除效果。 2018-12-31 更新聲明:切片系列文章本是分三篇寫(xiě)成,現(xiàn)已合并成一篇。合并后,修正了一些嚴(yán)重的錯(cuò)誤(如自定義序列切片的部分),還對(duì)行文結(jié)構(gòu)與章節(jié)銜接做了大量改動(dòng)。原系列的單篇就不刪除了,畢竟也是有單獨(dú)成...
摘要:然而,當(dāng)我們想要獲取被包裝函數(shù)的參數(shù)或源代碼時(shí),同樣不能得到我們想要的結(jié)果。這是在中的,版本已被修復(fù),參考。如同上面我們所看到的,可以幫我們解決和的問(wèn)題,但對(duì)于獲取函數(shù)的參數(shù)或源代碼則束手無(wú)策。 裝飾器基本概念 大家都知道裝飾器是一個(gè)很著名的設(shè)計(jì)模式,經(jīng)常被用于 AOP (面向切面編程)的場(chǎng)景,較為經(jīng)典的有插入日志,性能測(cè)試,事務(wù)處理,Web權(quán)限校驗(yàn), Cache等。 Python...
閱讀 695·2021-11-18 10:07
閱讀 2886·2021-09-22 16:04
閱讀 888·2021-08-16 10:50
閱讀 3360·2019-08-30 15:56
閱讀 1793·2019-08-29 13:22
閱讀 2700·2019-08-26 17:15
閱讀 1247·2019-08-26 10:57
閱讀 1116·2019-08-23 15:23