Python中的模块路径

6 投票
2 回答
5683 浏览
提问于 2025-04-16 15:37

我创建了一个文件夹,里面放了我GAE应用程序的所有模块,还有一些外部库,比如Jinja2,这样可以把所有东西整理在一个地方。我的文件夹结构是这样的:

lib\
   \utils\
         \__init__.py
   \firepython
   \jinja2
   \jsonpickle
   __init__.py
   sessions.py

当我试图从utils__init__.py加载Jinja时,出现了错误 ImportError: No module named jinja2.environment。我查看了Jinja2的导入说明,发现它们的写法是 from jinja2.loaders。我尝试把它改成 from lib.jinja2.loaders,但又出现了其他关于导入的错误。而且,我觉得如果有更方便、更正确的方法来导入模块,直接修改外部库的导入方式并不是一个好主意。我还在 PYTHONPATH 中添加了一些路径,但这并没有解决所有问题。我该如何正确导入放在其他文件夹中的外部包,尤其是当它的结构比较复杂时?

2 个回答

1

要正确导入一个模块,你需要确保Python知道在哪里可以找到它。为此,你可以在运行时把每个外部库的父目录添加到sys.path中,或者在运行之前设置PYTHONPATH环境变量。

举个例子:

import sys
sys.path.append('/my/lib')

# now we can import from lib
import jsonpickle # will load /my/lib/jsonpickle/__init__.py

想了解当你调用import时,Python到底做了什么,可以查看这个链接:http://docs.python.org/tutorial/modules.html#the-module-search-path

6

确实,你不应该需要去修改外部库里的导入内容,不过根据你的环境,有时候可能还是需要这样做。

PYTHONPATH

修改你的 PYTHONPATH 应该就能解决问题;PYTHONPATH 里应该包含一个 'lib' 路径,这个路径可以是绝对路径,也可以是相对于你家目录的相对路径,比如说:

然后你可以简单地这样做:

from jinja2 import WHATEVER

sys.path.append

除了使用 PYTHONPATH,另一种方法是用 sys.path.append() 在你的 Python 代码里添加路径。我其实更喜欢这种方法,因为它还可以让你为每个应用设置不同的路径。

使用 virtualenv

具体的细节这里说起来有点长,但请参考一下 官方文档

这些选项适用于一般的 Python 开发,而不是 GAE 的特定情况;如果在你的开发机器上不管用,你应该提供更多细节(比如确切的导入内容、绝对路径、pythonpath 等等)。

一个合适的项目结构和使用 appcfg.py 应该能在上传到 Google 时处理好依赖关系:请看看这个很好的回答:我该如何管理与 Google App Engine 相关的第三方 Python 库?(virtualenv?pip?),并遵循那些指导。

使用 GAE 的一个不错的方法是通过 yaml 应用指令。请查看文档中的包含部分:http://code.google.com/appengine/docs/python/config/appconfig.html#Includes

另外,请记得 GAE 官方支持 Python 2.5,而 2.7 的支持 还是实验性的

现在 Python 2.7 已经 正式支持

撰写回答