2017-09-06 53 views
2

我剛剛花了將近一個小時來追蹤當時的情況 - 這是一個非常令人困惑的錯誤消息。錯誤的來源是這個代碼塊(對於這個問題的目的,所有的作品的意義其實並不重要):避免被被污染的命名空間咬住

fspec_prsrs = tuple(compile('{{{}{}}}'.format(fstr_tup.field_name 
               if fstr_tup.field_name else '', 
               ':'+fstr_tup.format_spec 
               if fstr_tup.format_spec else '' 
              ) 
          ) 
        for fstr_tup in fstr_tuples) 

這就造成了這樣的錯誤:

*** TypeError: Required argument 'filename' (pos 2) not found 

錯誤的原因是我忽略了在文件頂部(從parse module)導入compile函數。因此,compile指的是built-in compile function。儘管現在我明白了錯誤信息,但我明白了原因,最後我浪費了一大堆時間來看看我認爲導入函數的包源代碼,認爲錯誤來自那裏。相反,它始終來自內置的compile

compile函數是我傾向於忘記的東西,即使存在。我很少用它,如果有的話,確實也有一些在內置列表功能就像compile,我也從來沒有使用(我看你id,並YOU,因此他們坐在那裏除了污染我的命名空間外別無所求。

通常,當忘記導入某些東西時,只會得到一個NameError,在這種情況下原因很明顯;但是當我在命名空間中潛藏的東西沒有放在那裏時,它就不那麼明顯了。是否有完整的方法來避免這樣的問題?

可以做些什麼?或者,這僅僅是每個Python編碼人員必須學會忍受的東西嗎?

+1

也許使用突出顯示內置名稱的IDE?這樣,如果你的代碼指的是內置的名字,這將是明確的。 Pycharm這樣做。以及崇高。 –

+0

@ChristianDean因爲我從來沒有經常使用IDE,所以對我來說這個解決方案並不明顯,儘管我相信這對於那些擁有這些解決方案的人來說似乎很明顯。我通常會說「我不需要IDE」(我只是使用Notepad ++),但是我想今晚我已經證明我是這樣做的。 –

回答

2

我有這個避免這個問題的唯一想法是不要將對象導入名稱空間開始。例如,而不是:

from parse import compile 

人會做:

import parse 
parse.compile(...) 

這解決了這個問題。但是,我不喜歡這個解決方案,因爲我打算從該模塊中的parse包中使用的唯一東西首先是compile。這對讀者來說更加直接和清晰(即Future Me)爲什麼什麼我正在使用parse模塊,當正在導入的內容是正確的時候。

更好的解決方案將是「設置它並忘記」的方式來消除全局命名空間中的事情,這些事情在我工作的模塊中對我無用。

+0

將'從解析導入編譯爲<某個唯一名稱>'適合未來你的理解嗎? – Eric

+0

@Eric我不知道......未來我很愚蠢。這是一個很好的建議,但我的抱怨是,爲了*記住*我需要做到這一點,我需要留意 - 今天* - 首要的名稱空間污染的污染......缺乏這種正念是開始的問題的根源。 –

+0

'from import '是一種相對容易grep的模式,所以您可以自動掃描您的代碼以瞭解這種畸變。或者你甚至可以爲[Pylint]寫一個插件(https://pylint.readthedocs.io/en/latest/how_tos/plugins.html)。 – Eric