如何在Google App Engine中导入模块?

23 投票
4 回答
16015 浏览
提问于 2025-04-15 22:00

我创建了一个简单的GAE应用,使用的是默认的模板。现在我想添加一个外部模块,比如short_url。请问我该怎么做呢?我找到的说明都很 confusing,而且我猜GAE似乎不使用PYTHONPATH,原因也很明显。

4 个回答

1

你可以把Python的包以ZIP文件的形式导入,这样可以避免文件数量过多的问题。

关于这个内容,应用引擎的文档有详细说明。

在Python 2.5中:支持zipimport。

在Python 2.7中:不支持zipimport,但Python 2.7可以直接从.zip文件导入。

这是我导入boto的方式。

sys.path.insert(0, 'boto.zip')
import boto #pylint: disable=F0401
from boto import connect_fps  #pylint: disable=F0401

这种方法的缺点是需要手动重新打包很多包。

举个例子,boto.zip解压后会变成一个名为“boto”的子文件夹,里面还有一个“boto”模块(作为另一个子文件夹)。

所以,如果你想正常导入boto,可能需要用到from boto import boto,但这样可能会因为缺少__init__.py而出现一些奇怪的问题。

解决这个问题的方法很简单,只需解压后,把boto子文件夹手动打包成boto.zip,然后把它放到你的应用文件夹里。

5

我同意@Adam Bernier和@S.Mark的回答,虽然Adam的解释更详细一些。一般来说,你可以把任何纯Python模块或包添加到你的App Engine目录中,并直接使用,只要它们不试图在沙盒外工作,也就是说,不能创建文件,不能打开网络连接等。

另外,要记住一些硬性限制:

  • 文件总数的最大限制(应用文件和静态文件):3000个
  • 单个应用文件的最大大小:10兆字节
  • 单个静态文件的最大大小:10兆字节
  • 所有应用文件和静态文件的总大小最大限制:150兆字节

更新(2011年10月):这些数字中的大部分已经增加到:

  • 文件总数的最大限制(应用文件和静态文件):10000个
  • 单个应用文件的最大大小:32MB
  • 单个静态文件的最大大小:32MB

更新(2012年6月):最后一个限制被提高到:

  • 所有应用文件和静态文件的总大小最大限制:1GB
30

只需将 short_url.py 文件放在你应用的目录里。

这是一个示例的 App Engine 项目:

myapp/
    app.yaml
    index.yaml
    main.py
    short_url.py
    views.py

然后在 views.py(或者其他地方),你可以这样导入:

import short_url

对于更复杂的项目,可能更好的方法是专门创建一个目录来放依赖项,比如叫 lib

myapp/
    lib/
        __init__.py
        short_url.py
    app.yaml
    index.yaml
    main.py
    views.py
from lib import short_url

编辑 #2:
抱歉,我应该早一点提到这个。你需要修改你的路径,感谢 Nick Johnson 提供的以下解决方案。
确保这段代码在启动你的应用之前运行;可以像这样:

import os
import sys

def fix_path():
    # credit:  Nick Johnson of Google
    sys.path.append(os.path.join(os.path.dirname(__file__), 'lib'))

def main():
    url_map = [ ('/', views.IndexHandler),] # etc.
    app = webapp.WSGIApplication(url_map, debug=False)
    wsgiref.handlers.CGIHandler().run(app)

if __name__ == "__main__":
    fix_path()
    main()

编辑 #3:
为了让这段代码在其他所有导入之前运行,你可以把路径管理的代码放在一个单独的文件里,放在你应用的根目录(Python 会自动识别这个目录里的所有内容,无需修改路径)。
然后你只需确保这个导入

import fix_path

...在你的 main.py 文件中的所有其他导入之前列出。
如果我的解释不够清楚,这里有一个 完整的工作示例链接

撰写回答