我在Python 3.3.1(win7)中有一个奇怪的NameError。
代码:
import re
# ...
# Parse exclude patterns.
excluded_regexps = set(re.compile(regexp) for regexp in options.exclude_pattern)
# This is line 561:
excluded_regexps |= set(re.compile(regexp, re.I) for regexp in options.exclude_pattern_ci)
错误:
Traceback (most recent call last):
File "py3createtorrent.py", line 794, in <module>
sys.exit(main(sys.argv))
File "py3createtorrent.py", line 561, in main
excluded_regexps |= set(re.compile(regexp, re.I) for regexp in options.exclude_pattern_ci)
File "py3createtorrent.py", line 561, in <genexpr>
excluded_regexps |= set(re.compile(regexp, re.I) for regexp in options.exclude_pattern_ci)
NameError: free variable 're' referenced before assignment in enclosing scope
请注意,发生错误的第561行是上面代码中的 second 行。换句话说:re
不是自由变量。它只是正则表达式模块,它可以在第一个行中完美地引用。
在我看来,对re.I
的引用导致了问题,但我不知道如何。
答案 0 :(得分:10)
最有可能的是,你在{em> 第561行以下的某个点分配re
(可能是无意中),但是在同一个函数中。这会再现您的错误:
import re
def main():
term = re.compile("foo")
re = 0
main()
答案 1 :(得分:8)
“自由变量”表明这是封闭范围内的局部变量。像这样的东西:
baz = 5
def foo():
def bar():
return baz + 1
if False:
baz = 4
return bar()
这样baz
指的是一个局部变量(值为4的那个),而不是(可能是现有的)全局变量。要解决此问题,请将baz
强制转换为全局:
def foo():
def bar():
global baz
return baz + 1
这样它就不会尝试将名称解析为非本地版本的baz。更好的是,以一种看起来像局部变量的方式找到你正在使用re
的位置(生成器表达式/列表推导是一个很好的检查位置),并将其命名为其他内容。
答案 2 :(得分:0)
其他解释是完美的,但让我添加我刚刚发现的另一个变体。由于Python 3比“物理”列表更喜欢迭代器,因此必须更加小心:
def foo():
re = 3
faulty = filter(lambda x: x%re, range(30))
del re
return faulty
list(foo())
仅在最后一行的return语句之后,尤其是在del re
之后,才对过滤器表达式求值。因此,最后一行因错误而爆炸:
NameError: free variable 're' referenced before assignment in enclosing scope