Python 交互模式模块导入问题

0 投票
2 回答
1261 浏览
提问于 2025-04-16 09:05

我觉得我遇到了一个范围问题,可能是命名空间的问题。我不太确定,因为我刚学Python。

我正在尝试制作一个模块,用正则表达式在列表中搜索。我相信有更好的方法来做到这一点,但我现在遇到的这个错误让我很烦恼,我想搞明白为什么会这样。

这是我的代码:

class relist(list):
 def __init__(self, l):
  list.__init__(self, l)

 def __getitem__(self, rexp):
  r = re.compile(rexp)
  res = filter(r.match, self)
  return res

if __name__ == '__main__':
    import re
    listl = [x+y for x in 'test string' for y in 'another string for testing']
    print(listl)
    test = relist(listl)
    print('----------------------------------')
    print(test['[s.]'])

当我在命令行运行这段代码时,它的表现和我预期的一样;但是当我在Python的交互模式下运行时,我却遇到了错误:

>>> test['[s.]']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "relist.py", line 8, in __getitem__
    r = re.compile(rexp)
NameError: global name 're' is not defined

在交互模式下,我确实导入了re模块,并且可以使用re的函数,但不知为何,当我尝试执行这个模块时,它却不工作。

我需要在类的范围内导入re模块吗?我觉得不需要,因为如果在当前范围找不到,Python不是会去其他范围查找吗?

感谢你的帮助,如果有更好的搜索方法,我也很想知道。谢谢!

2 个回答

2

把“import re”这行代码从底部的“if...”部分移到文件的最上面:

import re

class ....

这样做是因为你只有在把这个文件当作程序运行时才会导入re模块,而不是当作模块被其他文件导入。

(另外,Python的风格建议类名用大写字母开头。)

1

Python不会提前运行任何代码;它只会在遇到代码时才执行。唯一提前做的事情就是把源代码翻译成字节码。

当你导入一个模块时,__name__是模块的名字,而不是__main__。所以在最后的if块里的代码不会被执行,re模块也不会被导入。等到你想用这个类的时候,re的名字会在那一刻被查找(比如要用re.compile),但找不到(因为之前没有导入这个模块)。

撰写回答