如何在AWS Lambda分发压缩包中包含Python命名空间包?
AWS Lambda中使用Python命名空间包的解决方案
问题场景
你的Python命名空间包目录结构如下:
mypackage foo __init__.py bar.py
由于是命名空间包,顶层mypackage目录没有__init__.py。你将其与业务代码打包成如下结构部署到Lambda:
mypackage foo __init__.py bar.py my_app __init__.py handler.py
但handler.py中导入mypackage.foo.bar.ExampleClass时,出现"无法导入...,找不到模块mypackage"的错误,且不能给顶层mypackage添加__init__.py。
可行解决方案
1. 调整Python搜索路径(最直接)
Lambda的代码根目录是/var/task,默认情况下Python可能未将其完全纳入命名空间包的搜索路径,可通过两种方式修正:
- 环境变量配置:在Lambda控制台的「函数配置」→「环境变量」中,添加
PYTHONPATH变量,值设为/var/task。 - 代码内手动添加路径:在
handler.py的最开头添加以下代码:
import sys from pathlib import Path # 将项目根目录(/var/task)添加到Python搜索路径 sys.path.append(str(Path(__file__).parent.parent))
2. 用setuptools声明命名空间包
在mypackage目录下创建setup.py,明确声明命名空间,让Python正确识别该结构:
from setuptools import setup, find_namespace_packages setup( name="mypackage", version="0.1.0", packages=find_namespace_packages(include=["mypackage.*"]), namespace_packages=["mypackage"], )
更新后的打包结构如下:
mypackage setup.py foo __init__.py bar.py my_app __init__.py handler.py
部署后,Python会通过setuptools的命名空间机制找到mypackage。
3. 兼容PEP 420命名空间包
Lambda的Python运行时(3.3+)原生支持PEP 420命名空间包,只需确保根目录在搜索路径内。如果仍有问题,可在handler.py中补充如下代码:
import pkgutil import sys # 扩展命名空间搜索路径 __path__ = pkgutil.extend_path(__path__, __name__) sys.path.append('/var/task')
验证方法
可在handler.py中临时添加打印语句,确认Python搜索路径包含/var/task:
import sys print("Python搜索路径:", sys.path)
查看Lambda的执行日志,确认路径配置正确。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

