2010-11-05 229 views
2
for element in container: 
    # some code here 
    temp_variable = f1(element) 
    # more code 

# much later in the code 

for element in container: 
    # some code 
    another_variable = g(temp_variable) 
    # more code 
    temp_variable = f2(element) 
    # more code 

在第二for環與分配前變量使用錯誤,我意外它分配之前使用可變temp_variable。通常情況下,我會得到NameError異常,但不幸的是,它在之前的循環中存活,有效並初始化。蟒:避免在循環

是否有任何的編碼實踐,IDE工具等,這將有助於防止這種錯誤?

順便說一句,我就在想,如果在循環中的變量呆沒有生存過循環的結束可能會更好。

編輯

@Ignacio巴斯克斯 - 艾布拉姆斯:

如果我理解正確的話,建議您不要使用相同的變量名在多個循環的局部變量。我有兩個問題:

  1. 經常使用的最具描述性的變量名稱在多個循環中恰好相同。說,我用了unique_visitor_count之類的東西。我不想禁止這個變量在代碼中被進一步使用,在另一個循環中。

  2. 現有的代碼時,這將是非常繁重的檢查,如果我想使用任何新的變量名已經被使用過。

+4

我認爲最大的編碼習慣是首先不這樣做。 – 2010-11-05 02:06:09

回答

7

如果代碼中的'後期'太多,那麼你應該把代碼分解成多個函數。聽起來這個功能太長了。

另一個提示是使用有意義的名稱。 temp_variabletmptemp等都不是好名字。使用描述它指向的值的名稱。這將消除這類問題的一大類潛在事件。

而且,列表內涵不漏的變量,所以,如果你可以使用它們,比這只是一個原因是他們一般都比較好。但它們並不適用於所有情況。

+1

+1:我知道理解不會泄漏變量,但我從來沒有把兩個和兩個放在一起,所以沒有看到這個好處。感謝您提出。是的,我的功能太長了,我把它分開了。 – max 2010-11-09 17:18:45

4

如果您希望變量在循環結束後消失,請將循環重構爲函數。這樣,在函數被調用之後,變量將超出範圍並且將被垃圾收集。我建議你a)把這些需要臨時變量的函數放在函數中,b)單元測試(因爲第二個for循環將不會執行就其本身而言,僅用於for循環的單元測試會捕獲你的錯誤)。

+0

+1:循環的單元測試。至於重構,我同意,但我不能讓每個循環都起作用。當它太大而不能仔細閱讀時,我喜歡分解函數的方法。 – max 2010-11-09 17:20:12

+0

但是...你如何單元測試一個循環而不使它成爲一個單獨的函數? – max 2012-11-21 03:35:18

3

嘗試增加del temp_variable當你不再需要它。

+0

+1:不知道! – max 2010-11-09 17:15:16

0

嘗試運行pylint。它不會直接捕獲這樣的錯誤,但它會告訴你何時不使用變量的值。

3

如果你不想泄漏局部變量,其他人建議把代碼放在函數中。我想建議你將這些函數放入函數中。這樣他們就可以訪問在外部函數中定義的變量,所以你不必將它們傳入。只需在需要時定義內部函數並立即調用它們,除非它們可以被重用。

def myfunc(a): 

    i = 10 

    def infunc(): 
     for i in range(a): 
      print i, 
    infunc() 

    print i 

myfunc(5) 
>>> 0 1 2 3 4 10 

這不是特別漂亮,但它確實有效,而且你不應該經常需要它。

+0

+1只是在無法在任意位置創建名稱空間而掙扎,這似乎是最好的工具(醜陋,因爲它......)。 – max 2012-11-21 03:30:54

0

是否有任何編碼實踐,IDE工具等,這將有助於防止此類錯誤?

設計第一。代碼第二。