4

我在导入语句时遇到问题,因为 Python 报告没有名为 the_page 或 the_generator 的模块。

task_a.py 包含import generator.the_page as ThePage,当作为主脚本运行时,不会导致任何问题。

the_generator.py 包含import tasks.task_a,但是当我将它作为主脚本运行时,python 抛出以下错误..

Traceback (most recent call last):
  File "/generator/the_generator.py", line 7, in <module>
    import tasks.tasks_a
  File "/generator/tasks/tasks_a.py", line 3, in <module>
    import generator.the_page as ThePage
ImportError: No module named the_page

这是结构。

generator/
    __init__.py
    the_generator.py
    the_page.py
    tasks/
        __init__.py
        task_a.py

也许你可以帮助解决我的问题。感谢所有的帮助!

4

1 回答 1

10

从包的中间运行脚本是一个坏主意,原因有很多,其中最明显的是你遇到的那个:当你在import generator.the_generator某个地方,generator最终作为一个包,所以绝对导入generator.the_page, 或相对导入,会很好用。但是当你只是运行脚本generator/the_generator.py时,没有generator.the_generator,只是__main__,没有generator包。Python 可以知道如何查找的唯一另一种方法generator.the_page是,如果父目录generator是 on sys.path,它不是。

您可以猜到,您可以通过将适当的父目录放在那里来解决这个sys.path问题……但这也是一个坏主意。

此解决方案还有许多其他问题。最严重的是,它很容易导致同一个模块被导入两次(因为 Python 无法知道两个明显不相关的名称恰好引用同一个模块)。它也很难部署(/usr/local/bin如果它依赖于包内,则无法安装脚本......),如果您的包用完 .zip 或 .egg 等,它将无法工作。


有两种标准方法可以解决这个问题。

首先,只需将脚本作为模块而不是作为脚本运行。从 的父目录generatorpython -m generator.the_generator而不是python generator/the_generator.py.

这样做的一个主要优点是它在正常安装的部署中工作得一样好,当generator它在某个地方的站点包中时,就像在测试中一样。

或者,创建一个位于 旁边的脚本generator并运行它,而不是其中的模块。这可以像将所有if __name__ == '__main__':代码移动the_generator.py到一个函数中一样简单,然后编写两行包装器:

import generator.the_generator
generator.the_generator.main()

同样,这在正常安装的部署中也同样有效。另外,这意味着脚本可以安装到您的bin目录中,使事情变得更加容易,就像pipipython.

于 2013-08-28T19:14:09.533 回答