【问题标题】:Python NameError when attempting to use a user-defined class尝试使用用户定义的类时出现 Python NameError
【发布时间】:2010-04-10 21:27:49
【问题描述】:

尝试使用我编写的类时,我遇到了一个奇怪的 NameError 实例。在一个目录中,我有以下文件结构:

  • 目录/
    • ReutersParser.py
    • test.py
    • reut-xxx.sgm

我的自定义类在 ReutersParser.py 中定义,我在 test.py 中定义了一个测试脚本。

ReutersParser 看起来像这样:

from sgmllib import SGMLParser

class ReutersParser(SGMLParser):

    def __init__(self, verbose=0):
        SGMLParser.__init__(self, verbose)

    ... rest of parser

if __name__ == '__main__':

    f = open('reut2-short.sgm')
    s = f.read()

    p = ReutersParser()
    p.parse(s)

它是处理路透社文章的 SGML 文件的解析器。测试完美运行。不管怎样,我打算在test.py中使用它,它看起来像这样:

from ReutersParser import ReutersParser

def main():
    parser = ReutersParser()

if __name__ == '__main__':
    main()

当它到达那个解析器行时,我收到了这个错误:

Traceback (most recent call last):
  File "D:\Projects\Reuters\test.py", line 34, in <module>
    main()
  File "D:\Projects\Reuters\test.py", line 19, in main
    parser = ReutersParser()
  File "D:\Projects\Reuters\ReutersParser.py", line 38, in __init__
    SGMLParser.__init__(self, verbose)
NameError: global name 'sgmllib' is not defined

由于某种原因,当我尝试在 test.py 中使用我的 ReutersParser 时,它会抛出一个错误,提示它找不到内置模块 sgmllib。我束手无策,试图弄清楚为什么导入不起作用。

是什么导致了这个 NameError?我已经尝试在我的 test.py 中导入 sgmllib 并且有效,所以我不明白为什么在尝试为我的 ReutersParser 运行构造函数时找不到它。

【问题讨论】:

  • 您使用的是哪个版本的 Python?我在 linux 上使用 Python 2.5.2,你的代码运行良好。
  • 我也无法重现(Windows 上的 Python 2.6);但是,我记得前段时间当类名与模块名相同时,导入时遇到了一些问题。我不知道这是否有帮助,但您至少可以尝试一下。
  • 我已经在 Windows 和 SunOS 5.8 上使用 2.6.5 进行了尝试。我会尝试稍微更改类的名称并更新。谢谢!
  • 更新:我将类名更改为 ReutersParserChange。现在它似乎工作了。看来罗伯托的建议是问题的根源。有人知道为什么吗?

标签: python


【解决方案1】:

您的问题不在于您的代码,而在于您运行它的内容。如果您阅读了错误及其显示的代码:

  File "D:\Projects\Reuters\ReutersParser.py", line 38, in __init__
    SGMLParser.__init__(self, verbose)
NameError: global name 'sgmllib' is not defined

您会注意到 Python 认为会产生此错误的行中没有对“sgmllib”的引用。这意味着两件事之一:要么错误不是源自那里(Python 非常混乱),要么正在显示的代码不是正在执行的代码。例如,当您在不重新启动代码执行之间的 Python 解释器的 IDE 中运行代码时,后者很常见。它将执行您的旧代码,但在显示回溯时将显示新代码。我猜你在过去的某个时候在那条线上做过sgmllib.SGMLParser.__init__(self, verbose)

通过重命名类来修复它的原因可能是您做了一些事情——比如编辑代码——导致 IDE 重新启动解释器、正确清理它或(意外地)重新加载了正确的模块让它看到新代码的正确方法。因为你在你的类之后命名你的模块(顺便说一下,这是不好的风格)我假设你在重命名你的类时重命名了你的模块,所以你的 IDE 这次选择了新代码。当然,直到下一次同样的事情发生。

【讨论】:

  • 啊,好吧。我不知道 IDLE 做了这样奇怪的事情。将来我必须更加小心。谢谢!
猜你喜欢
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
相关资源
最近更新 更多