簡體   English   中英

為什么Python lint要求我使用不同的局部變量名而不是全局變量名

[英]why does Python lint want me to use different local variable name, than a global, for the same purpose

給定Python代碼如

def func():
    for i in range(10):
        pass

for i in range(10):
    pass  

pylint抱怨

Redefining name 'i' from outer scope 

什么是Pythonic寫上面的方法? 在本地使用不同的變量,比如j

但是,為什么,當變量在兩種情況下都意味着完全相同( i代表索引)。 假設我將所有本地索引更改為j ,然后我發現我想使用j作為glocal范圍中的第二個索引。 要改變一下嗎?

我無法禁用lint警告,我不想擁有它們,我想寫Pythonic,但我想在同樣的事情中使用相同的名稱,在上面的簡單情況下。 這不可能嗎?

您可以通過不使用任何全局變量來避免全局變量沖突:

def func():
    for i in range(10):
        pass

def _init_func():
    for i in range(10):
        pass  

_init_func()

任何需要在模塊初始化時運行的代碼都可以放在一個函數中。 這留下了作為模塊init期間運行的唯一可執行代碼: def語句, class語句和一個函數調用。

同樣,如果您的代碼不是要import ,而是要運行的腳本,

def func():
    for i in range(10):
        pass

def main():
    for i in range(10):
        pass  

if __name__=="__main__":
    main()

因為當你相信你正在使用另一個時,它可以消除使用它的風險。 Lint工具可以使您的代碼更加健壯。 通過使所有變量具有不同的名稱,可以確保不會出現此類沖突。

這在解釋語言中尤其重要,因為在“編譯時”不會檢查錯誤。 我曾經有過第二次調用函數給我一個錯誤的問題,因為我重命名了一個函數而我沒有意識到在某些情況下有一個變量是用我的函數創建的,所以,當我試圖調用我的函數時,解釋器試圖“調用”我新創建的變量,它從未使用過XD。

這種棉絨政策將避免這種問題。

這是一個示例代碼(這是一個計算pi的程序):

from fractions import Fraction


def order(x):
    r, old_r, n, old_n = 2, 1, 1, 0
    while (x>=r):
        r, old_r, n, old_n = r*r, r, 2*n, n
    return order(x >> old_n) + old_n if old_n > 0 else 0


def term(m, n, i):
    return Fraction(4 * m, n**(2*i+1) * (2*i+1))


def terms_generator(exp_prec):
    ws = [ [term(parm[1], parm[2], 0), 0] + list(parm)
          for parm in ((1, 44, 57),
                       (1, 7, 239),
                       (-1, 12, 682),
                       (1, 24, 12943))]
    digits = 0
    while digits<exp_prec:
        curws = max(ws, key=lambda col: col[0])
        digits = int(0.30103 *
                     (order(curws[0].denominator))
                      - order(curws[0].numerator))
        yield curws[2] * curws[0], digits
        curws[2] = -curws[2]                
        curws[1] += 1
        curws[0] = term(curws[3], curws[4], curws[1])

expected_precision = 1000
pi = 0
for term, dgts in terms_generator(expected_precision):
    pi += term

print("{} digits".format(dgts))
print("pi = 3.{}".format(int((pi-3)*10**expected_precision)))

在這種情況下,我從生成器初始化了一個變量,並且生成器使用了另一個函數,該函數在我的生成器初始化后與我的變量名沖突。 嗯,這不是一個很好的例子,因為這兩個名字都是全局的,但從它的結構來看,它不會立即顯現出來。

我的觀點是,即使你知道如何編程,你也會犯錯誤,這些做法將有助於降低那些隱藏的風險。

如果它至少運行一次,那么linter警告因為 i在循環之后繼續生活。 這意味着如果您在不重新初始化的情況下使用它,它仍將具有在循環的最后一次迭代期間具有的值。

你使用它的方式很好,因為 i將永遠重新初始化。

一個有用的做法可能是在 ALL_CAPSALL_CAPS外部作用域中的所有值。 這樣就不會犯錯誤。

這個答案理所當然地被認為是錯誤的。 請參閱: https//stackoverflow.com/a/25072186

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM