如何配置setup.py实现import foo.bar的全限定导入?
问题
当前目录结构如下:
/tmp/foo |-- bar `-- __init__.py `-- setup.py
对应的setup.py代码:
from setuptools import find_packages, setup package_name = 'foo' module_name = 'bar' setup( name=package_name, packages=find_packages(), # 尝试过的配置: # 完全省略package_dir # package_dir={'': module_name}, # package_dir={package_name: module_name}, python_requires=">=3.6", )
试过多种package_dir配置,部分能让import foo生效,但始终没法实现import foo.bar的全限定导入,怎么解决?
解决办法
核心问题是目录结构和包的层级映射不匹配,下面给两种可行方案:
方案1:调整目录结构(推荐)
把bar目录放到一个名为foo的子目录里,让目录结构符合Python包的层级规范,调整后目录结构如下:
/tmp/foo |-- foo |-- bar | `-- __init__.py `-- __init__.py `-- setup.py
此时setup.py不用额外配置package_dir,直接用默认配置就行:
from setuptools import find_packages, setup package_name = 'foo' setup( name=package_name, packages=find_packages(), python_requires=">=3.6", )
安装后就能正常执行import foo和import foo.bar。
方案2:通过package_dir映射层级(不推荐,仅适配现有目录)
如果不想改目录结构,就得在setup.py里明确映射foo包及其子包的路径,而且不能用find_packages(),得手动指定包列表:
from setuptools import setup package_name = 'foo' module_name = 'bar' setup( name=package_name, packages=[package_name, f"{package_name}.bar"], package_dir={ package_name: '.', # 将当前目录映射为foo包的根目录 f"{package_name}.bar": module_name # 将bar目录映射为foo.bar子包 }, python_requires=">=3.6", )
内容的提问来源于stack exchange,提问作者A T
相关产品推荐
相关产品推荐

