自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python開發(fā)人員最常見的8個錯誤

新聞 前端
大多數(shù)python開發(fā)人員具有不同的核心編程語言背景,例如java,C?;騝 ++。 因此,他們習(xí)慣于用艱苦的方式做事,而當(dāng)它們以簡單易學(xué)的Python語言被引入時,它們會誤解Python的多樣性和功能,并常常最終導(dǎo)致自己誤導(dǎo)其失去某些細(xì)微之處。

 大多數(shù)python開發(fā)人員具有不同的核心編程語言背景,例如java,C?;騝 ++。 因此,他們習(xí)慣于用艱苦的方式做事,而當(dāng)它們以簡單易學(xué)的Python語言被引入時,它們會誤解Python的多樣性和功能,并常常最終導(dǎo)致自己誤導(dǎo)其失去某些細(xì)微之處。

在本文中,我將嘗試解決Python程序員遇到的錯誤。 這些錯誤甚至是本文中的大多數(shù)錯誤都是針對中級甚至專家級的開發(fā)人員的。 想知道? 如果您是初學(xué)者或中級開發(fā)人員,請繼續(xù)閱讀文章Python開發(fā)人員最常犯的10個錯誤,因為當(dāng)前文章適合更高級的讀者。

Python開發(fā)人員最常見的8個錯誤

1.遍歷列表時修改列表

這是每個Python開發(fā)人員一生中至少面對一次的問題。在下面的代碼片段中查看問題:

  1. >>> odd = lambda x : bool(x % 2
  2. >>> numbers = [n for n in range(10)] 
  3. >>> for i in range(len(numbers)): 
  4. ...     if odd(numbers[i]): 
  5. ...         del numbers[i]  # 在列表上進行迭代時刪除列表中的項目...Traceback (most recent call last):      File "<stdin>", line 2, in <module> 
  6. IndexError: list index out of range 

這個問題非常明顯,但即使是高級開發(fā)人員,在復(fù)雜的工作流程中添加代碼時也會犯類似的錯誤。

有幾種解決方案。我想在這里討論一個最佳解決方案,但據(jù)我說這是最簡單的解決方案,因此我不太可能產(chǎn)生錯誤。我建議列表理解在這種情況下非常有用。看看上面的代碼具有列表理解的實現(xiàn):

  1. >>> odd = lambda x : bool(x % 2
  2. >>> numbers = [n for n in range(10)] 
  3. >>> numbers[:] = [n for n in numbers if not odd(n)] 
  4. >>> numbers 
  5. [02468

2.創(chuàng)建循環(huán)模塊依賴項

假設(shè)您有兩個文件a.py和b.py,每個文件都導(dǎo)入另一個文件,如下所示:

在a.py中:

  1. import b 
  2. def f():    return b.x 
  3.     print f() 

在b.py中:

  1. import a 
  2. x = 1 
  3. def g(): 
  4.     print a.f() 

首先,讓我們嘗試導(dǎo)入a.py:

  1. >>> import a 
  2. 1 

一切正常,沒有錯誤。它應(yīng)該給您一個錯誤,但是這里的問題是,如果存在循環(huán)依賴關(guān)系,您有時可以擺脫它,因為python足夠聰明,可以跟蹤導(dǎo)入的軟件包。當(dāng)每個模塊嘗試訪問另一個模塊的功能時會發(fā)生問題,因為不會聲明另一個模塊,這將導(dǎo)致AttributeError,如下所示:

  1. >>> import b 
  2. Traceback (most recent call last):        File "<stdin>", line 1, in <module> 
  3.       File "b.py", line 1, in <module> 
  4.     import a 
  5.       File "a.py", line 6, in <module> 
  6.     print f() 
  7.       File "a.py", line 4, in f 
  8.     return b.x 
  9. AttributeError: 'module' object has no attribute 'x' 

要解決此問題,我們需要在函數(shù)內(nèi)部導(dǎo)入其他依賴模塊:

  1. x = 1 
  2. def g():    import a    # 僅在調(diào)用g()時才會計算 
  3.     print a.f() 

現(xiàn)在一切都應(yīng)該運行良好:

  1. >>> import b 
  2. >>> b.g()1  #自模塊'a'在最后調(diào)用'print f()'以來首次打印 
  3. 1   #第二次打印,這是我們對“ g”的調(diào)用 

3.錯誤使用表達(dá)式作為函數(shù)參數(shù)的默認(rèn)值

這是很難調(diào)試的錯誤之一,因為它不會給您帶來錯誤,而且在大多數(shù)情況下它可以正常工作,并且開發(fā)人員可以擺脫它。當(dāng)我們可以指定一個可變的可選函數(shù)參數(shù)時,就會發(fā)生這種情況。例如:

  1. >>> def foo(bar=[]): 
  2. ...    bar.append("baz"
  3. ...    return bar 

看起來我們已經(jīng)創(chuàng)建了一個函數(shù),該函數(shù)會將baz附加在指定給它的列表的末尾,否則每次在不使用bar參數(shù)的情況下調(diào)用它都將返回[“ baz”],因為bar將被初始化為[]。但是,當(dāng)我們執(zhí)行它時,我們得到以下結(jié)果:

  1. >>> foo() 
  2. ["baz"
  3. >>> foo() 
  4. ["baz""baz"
  5. >>> foo() 
  6. ["baz""baz""baz"

輸出結(jié)果并非預(yù)期的那樣,現(xiàn)在您將看到,如果沒有人注意到此問題,那么如果調(diào)用它,大多數(shù)開發(fā)人員將如何擺脫它。通過查看代碼,很難找到尚未遇到此問題或不知道Python如何評估函數(shù)的人,因為每次它將bar的值初始化為[]時,都很難。但是在Python中,默認(rèn)參數(shù)僅被評估一次,因此在第一次調(diào)用時它會按預(yù)期工作,但是在第二次和第三次調(diào)用中,它使用現(xiàn)有的條形列表而不是對其進行初始化。她是我們?nèi)绾谓鉀Q這個問題的方法:

  1. >>> def foo(bar=None): 
  2. ...    if bar is None:      #或者 if not bar: 
  3. ...        bar = [] 
  4. ...    bar.append("baz"
  5. ...    return bar 
  6. ...>>> foo()["baz"
  7. >>> foo()["baz"
  8. >>> foo()["baz"

4.錯誤使用類變量

考慮以下示例:

  1. >>> class A(object): 
  2. ...     x = 1 
  3. ... 
  4. >>> class B(A): 
  5. ...     pass 
  6. ...>>> class C(A): 
  7. ...     pass 
  8. ...>>> print A.x, B.x, C.x 
  9. 1 1 1 

這個說得通。

  1. >>> B.x = 2 
  2. >>> print A.x, B.x, C.x 
  3. 1 2 1 

再次如預(yù)期

  1. >>> A.x = 3 
  2. >>> print A.x, B.x, C.x 
  3. 3 2 3 

什么?通過更改A類的值,C類不會受到影響是很奇怪的。這是因為在Python中,類變量在內(nèi)部作為字典處理,并且遵循稱為“方法解析順序”的順序。發(fā)生這種情況是因為在類C中找不到屬性x,所以在基類A中對其進行了查找。

5.為異常塊指定不正確的參數(shù)

對于給定的代碼:

  1. >>> try
  2. ...     l = ["a""b"
  3. ...     int(l[2]) 
  4. ... except ValueError, IndexError:  # To catch both exceptions, right? 
  5. ...     pass...Traceback (most recent call last):  File "<stdin>", line 3, in <module> 
  6. IndexError: list index out of range 
  7. 追溯(最近一次通話):  <模塊>中第3行的文件“ <stdin>” 
  8. IndexError:列表索引超出范圍 

看來您正在嘗試捕獲這兩個異常,但這是行不通的。此錯誤通常是由來自python 2.x背景的開發(fā)人員犯的,因為在Python 2中,此語法用于將異常綁定到可選參數(shù)。我們的代碼應(yīng)該捕獲了IndexError異常。正確的方法是使用元組,方法是指定要在元組中捕獲并使用as綁定到參數(shù)的所有異常。 python 2&3也支持此語法:

  1. >>> try
  2. ...     l = ["a""b"
  3. ...     int(l[2]) 
  4. ... except (ValueError, IndexError) as e:   
  5. ...     pass 
  6. ...>>> 

6.對Python作用域規(guī)則的誤解

Python范圍解析基于所謂的LEGB規(guī)則,它是Local,Enclosing,Global,Built-in的簡寫。但這會使開發(fā)人員遇到麻煩,例如:

  1. >>> x = 10 
  2. >>> def foo(): 
  3. ...     x += 1 
  4. ...     print x...>>> foo()Traceback (most recent call last):  File "<stdin>", line 1, in <module> 
  5.   File "<stdin>", line 2, in foo 
  6. UnboundLocalError: local variable 'x' referenced before assignment 
  7. 追溯(最近一次通話): 
  8.   <模塊>中第1行的文件“ <stdin>” 
  9.   文件“ <stdin>”,第2行,在foo中 
  10. UnboundLocalError:分配前已引用局部變量“ x” 

沒道理我們已經(jīng)聲明x應(yīng)該可以正常運行。調(diào)用該函數(shù)會在這里尋找變量x,但找不到變量x,它將把它帶到外部作用域。直到我們對其進行分配之前,它都可以正常工作。我們得到UnboundLocalError以避免函數(shù)意外更改變量的值。有關(guān)更多信息,請參見此處。

為了進一步說明,下面是一些其他示例:

  1. >>> lst = [123
  2. >>> def foo1(): 
  3. ...     lst.append(5
  4. ...>>> foo1()>>> lst[1235
  5. >>> lst = [123
  6. >>> def foo2(): 
  7. ...     lst += [5
  8. ...>>> foo2()Traceback (most recent call last):  File "<stdin>", line 1, in <module> 
  9.   File "<stdin>", line 2, in foo 
  10. UnboundLocalError: local variable 'lst' referenced before assignment 
  11. 追溯(最近一次通話): 
  12.   <模塊>中第1行的文件“ <stdin>” 
  13.   文件“ <stdin>”,行2,在foo中 
  14. UnboundLocalError:分配前已引用局部變量“ lst” 

在這兩種情況下,我們都嘗試從外部范圍更新列表。在第一個示例中它起作用了,但是在第二個示例中卻沒有起作用,因為我們在函數(shù)主體中的該列表上使用了賦值運算符。這將嘗試將計算/評估的值存儲到foo2中不存在的局部變量lst中。

7.混淆Python如何在閉包中綁定變量

考慮以下示例:、

  1. >>> def create_multipliers(): 
  2. ...     return [lambda x : i * x for i in range(5)] 
  3. >>> for multiplier in create_multipliers(): 
  4. ...     print multiplier(2
  5. ... 

您可能期望以下輸出:

  1. 0 
  2. 2 
  3. 4 
  4. 6 
  5. 8 

但是您實際上得到:

  1. 8 
  2. 8 
  3. 8 
  4. 8 
  5. 8 

由于Python的后期綁定行為,即在調(diào)用內(nèi)部函數(shù)時會搜索閉包中使用的變量的值。因此,在上面的代碼中,無論何時調(diào)用任何返回的函數(shù),i的值都會在調(diào)用時在周圍的范圍內(nèi)進行搜索,但是到發(fā)生這種情況時,循環(huán)就完成了,因此我已經(jīng)為其分配了i最終值為4。一種解決方法是:

  1. >>> def create_multipliers(): 
  2. ...     return [lambda x, i=i : i * x for i in range(5)] 
  3. ...>>> for multiplier in create_multipliers(): 
  4. ...     print multiplier(2
  5. ... 
  6. 0 
  7. 2 
  8. 4 
  9. 6 
  10. 8 

8.重新發(fā)明輪子

這是在來自低級語言背景(例如c ++,c#等)的開發(fā)人員中最常見的。由于龐大的社區(qū)和大量的開放源代碼內(nèi)容以及對python社區(qū)的幫助,如果沒有現(xiàn)有的解決方案,很難發(fā)現(xiàn)問題。但是在這里,我談?wù)摰氖侵匦聞?chuàng)建python提供的基礎(chǔ)。其中一些可能包括使用裝飾器,生成器,內(nèi)置函數(shù)。我最好的例子是排序功能。當(dāng)我為開發(fā)人員編寫滿足其獨特需求的自定義排序函數(shù)時,我已經(jīng)看到了好幾次。在所有情況下,整個功能都可以用更簡單,更優(yōu)雅和更強大的代碼代替:

  1. list.sort(key=…, reverse=…) 

很難找到無法解決我們問題的實際方案。我們甚至可以使用此方法對元組,字典或任何Python對象進行排序。

看下面的例子:

  1. >>> vowels = ['e''a''u''o''i'
  2. >>> vowels.sort(reverse=True) 
  3. >>> print('Sorted list (in Descending):', vowels) 
  4. Sorted list (in Descending): ['u''o''i''e''a'

這是元組列表的示例

  1. # take second element for sort#將第二個元素進行排序 
  2. def takeSecond(elem):    return elem[1
  3. # random list#隨機列表 
  4. random = [(22), (34), (41), (13)] 
  5. # sort list with key#用鍵排序列表 
  6. random.sort(key=takeSecond) 
  7. # print list#打印清單 
  8. print('Sorted list:', random) 
  9. Output: Sorted list: [(41), (22), (13), (34)] 

總結(jié):

即使python很容易上手,但對所使用的工具或范例缺乏深入的了解也會使您陷入麻煩。我希望你們中的一些人會發(fā)現(xiàn)

 

責(zé)任編輯:張燕妮 來源: 今日頭條
相關(guān)推薦

2015-09-21 09:34:57

2019-04-24 08:56:34

Java開發(fā)人員常犯錯誤

2015-09-15 10:42:06

2025-03-31 08:00:00

Django開發(fā)Python

2020-04-20 18:15:46

開發(fā)自信技術(shù)

2022-12-29 08:27:03

Java開發(fā)人員編碼

2024-11-08 15:22:08

2020-05-25 16:36:19

開發(fā)工具編碼

2020-05-17 16:10:36

開發(fā)人員軟件開發(fā)開發(fā)

2023-02-02 08:00:00

SQLJava開發(fā)

2022-09-04 15:28:25

開發(fā)React程序員

2011-07-10 15:18:11

開發(fā)

2020-06-09 07:57:47

前端開發(fā)代碼

2023-02-06 18:27:00

開發(fā)人員語言

2019-08-27 14:21:44

Python 開發(fā)程序員

2019-07-12 13:59:21

Docker軟件技術(shù)

2015-10-13 10:00:04

Web開發(fā)人員網(wǎng)站

2010-02-24 13:45:40

Python開發(fā)人員

2011-06-20 08:43:15

Windows 8開發(fā)人員

2022-12-03 00:15:08

點贊
收藏

51CTO技術(shù)棧公眾號