1

我正在尝试运行 Django 站点的manage.py脚本,但它失败并出现以下错误:

Traceback (most recent call last):
  File "manage.py", line 2, in <module>
    from django.core.management import execute_manager
  File "/scratch/tools/lib/python2.5/site-packages/django/core/management/__init__.py", line 4, in <module>
    from optparse import OptionParser, NO_DEFAULT
ImportError: cannot import name NO_DEFAULT

无论我使用 Python 2.5.1 还是 2.6.1(Fedora 包),都会发生这种情况。在交互式 Python 会话中进行导入时,我可以重现该错误。

这并不奇怪,因为NO_DEFAULT它没有在optparse.py's__all__中列出,也没有在optparse文档中列出。

那么,令人惊讶的是,在我自己的工作站上,我可以from optparse import NO_DEFAULT在 Python 2.5.5 和 2.6.6(Debian 软件包)中成功完成。

我的问题是双重的:

  • 我怎么能导入未列出的东西__all__
  • 我应该如何修复 Django manage.py?如果可能的话,我希望它与 Python 2.5 一起工作。
4

1 回答 1

0

与 Python 中的往常一样,__all__它更像是一种指导而不是规则。它的出现是因为 we-love-to-hate-it *-import,在文档中描述为

如果标识符列表被星号 ('*') 替换,则模块中定义的所有公共名称都绑定在 import语句的本地命名空间中。

这里有一个直接的技术难题:解释器应该如何知道模块的公共名称是什么?有一个约定,模块中不以 an 开头的任何名称_都是公共的;您可能会认为作为第一个近似值,应该简单地将所有此类名称导入模块的命名空间中。不幸的是,当您引入包时,这变得更加复杂,因为计算公共名称成为一项涉及各种导入、路径重写、文件读取以及您拥有的东西的大型任务。这不是一件好事。因此,简化的决定是允许模块作者通过在模块中定义来准确指定应该从 *-import 导入包中的哪些名称__all__

但是如果你不 *-import——如果你给解释器你想要导入的变量的名字——那么它就不需要担心找到所有的全局名称,所以它可以忽略__all__并只查找模块命名空间中的名称。

这确实意味着它__all__可能与locals().keys()不以下划线开头的子集不同。特别是,模块中可能有完美的对象,它们不是由 *-imports 导出的。这就是NO_DEFAULT.

于 2011-07-18T12:29:47.567 回答