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