Python:NameError:在封闭范围中赋值之前引用的自由变量're'

rob*_*ert 11 python

我在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)
Run Code Online (Sandbox Code Playgroud)

错误:

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
Run Code Online (Sandbox Code Playgroud)

请注意,发生错误的第561 行是上面代码中的第二行.换句话说:re不是自由变量.它只是正则表达式模块,它可以在第一行完全引用.

在我看来,引用re.I是导致问题,但我不知道如何.

ale*_*xis 12

最有可能的是,你第561行以下的re某个点分配(可能是无意中),但是在同一个函数中.这会再现您的错误:

import re

def main():
    term = re.compile("foo")
    re = 0

main()
Run Code Online (Sandbox Code Playgroud)

  • 你是对的。我将re模块再次导入到该行下的某个位置(本地导入到函数范围内)。但是我没有得到的是为什么Python然后不抱怨第一行... (2认同)
  • 你的代码没有在第12行引发,因为iterable是空的; 所以genexp的身体没有运行. (2认同)

Sin*_*ion 10

回溯中的"自由变量"表明这是封闭范围内的局部变量.这样的事情:

 baz = 5

 def foo():
     def bar():
         return baz + 1

     if False:
          baz = 4

     return bar()
Run Code Online (Sandbox Code Playgroud)

所以它baz指的是一个局部变量(值为4的那个),而不是(可能是现有的)全局变量.要修复它,强制baz全局:

 def foo():
     def bar():
         global baz
         return baz + 1
Run Code Online (Sandbox Code Playgroud)

这样它就不会尝试将名称解析为非本地版本的baz.更好的是re,以一种看起来像局部变量的方式找到你正在使用的位置(生成器表达式/列表推导是一个很好的检查位置),并将其命名为其他东西.