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

时间:2017-09-06 01:46:32

标签: python namespaces

我花了差不多一个小时来追踪当时的情况 - 这是一个非常令人困惑的错误信息。错误的来源是这段代码(为了这个问题的目的,所有部分的含义确实无关紧要):

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

错误的原因是我忽略了在文件顶部导入compile函数(来自parse module)。

因此,compile指的是built-in compile function。虽然错误信息现在对我来说非常清楚,因为我理解了原因,但我最后浪费了大量时间查看包含源代码的思想我导入了该函数,认为错误是来自那里。相反,它始终来自内置compile

compile函数是我倾向于忘记甚至存在的东西。我几乎没有使用它,如果有的话,内置列表中有许多功能,就像compile一样,我也从不使用(我正在看id filter!),因此他们坐在那里除了污染我的命名空间外什么也没做。

通常在忘记导入某些内容时,只会得到一个NameError,在这种情况下原因是显而易见的;但是当命名空间中潜藏着的东西我没有放在那里时,它就不那么明显了。是否有完全证明的方法来避免这样的问题?

可以做些什么?或者这只是每个Python程序员必须学会忍受的东西?

1 个答案:

答案 0 :(得分:2)

我唯一能避免此问题的想法是不要将对象导入命名空间中。例如,而不是:

from parse import compile

一个人会这样做:

import parse
parse.compile(...)

这解决了这个问题。但是,我不喜欢这个解决方案,因为我计划在该模块中parse包中使用的唯一内容是compile。对于读者来说,它有点直接和清晰(即Future Me)为什么 WHAT 当我正在使用parse模块时导入就在前面。

更好的解决方案是“设置并忘记”从全局命名空间中消除我在我工作的模块中对我无用的东西。