避免被被污染的命名空间咬住

问题描述:

我刚刚花了将近一个小时来追踪当时的情况 - 这是一个非常令人困惑的错误消息。错误的来源是这个代码块(对于这个问题的目的,所有的作品的意义其实并不重要):避免被被污染的命名空间咬住

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 ++),但是我想今晚我已经证明我是这样做的。 –

我有这个避免这个问题的唯一想法是不要将对象导入名称空间开始。例如,而不是:

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