如何使用子包正确打包Python3应用

时间:2019-06-11 20:56:28

标签: python python-import setup.py pypi python-packaging

我有一个包s3_backend,其中包含一个模块api.py,以及一个子包util,其本身包含5个模块。我想将其打包并上传到PyPI,以便人们可以pip install package并在顶层软件包中使用脚本API api.py。这两个软件包(s3_backend和's3_backend.util')都包含_init__.py文件。

整个项目保存在具有以下结构的目录project

project
    |- s3_backend (package)
        |- __init__.py
        |- util (package)
            |- __init__.py
            |- module1.py
            |...
            |- module5.py
        |- api.py
    |- setup.py

api.py本身会导入modules1-4

在本地project中,我可以     导入api     api.func1()... 没有错误。当我将软件包上传到TestPyPI并将其安装在新目录中的virtualenv中时,我遇到了问题,这些问题可以追溯到api.py中的import语句,该语句从子软件包{{1 }}。

此行     来自util导入模块1,模块2,模块3,模块4 引发此错误     没有模块名称“ util” 当我运行此命令     从s3_backend import util

我可以成功

modules1-4

s3_backend.util

显示

import s3_backend

setup.py的内容如下所示。在setup.py中处理子包的正确方法是什么?我在编写导入语句时错了吗?

要解决此问题,我尝试替换

help(s3_backend)

api.py
util (package)

from util import ...

但是这些在本地引起了问题。

setup.py的源代码:

from .util import ... 

api.py中的导入语句:

from s3_backend.util import ... 

请让我知道您是否还需要其他帮助。谢谢!

SkippyElvis

1 个答案:

答案 0 :(得分:1)

您可以尝试改用setuptools吗?只要要包含的每个文件夹中都有一个 init .py文件,find_packages函数就可以很好地发挥作用。

这是您需要在setup.py中使用的

# project/setup.py
from setuptools import setup, find_packages

setup(
  name='s3_backend',
  version='0.1.7',
  license='MIT',
  description='scripting api for file upload to s3',
  author='SkippyElvis',
  author_email='Skippy@Elvis.com',
  url='https://github.com/jackhwolf/s3_backend',
  keywords=['aws', 's3', 'file upload'],
  packages=find_packages(),
  classifiers=[
    'Programming Language :: Python :: 3',
  ],
)

否则,您可以使用macguyver函数来模仿find_packages。我不建议这样做。

对于您的导入,我主张使用绝对的根级导入。这样做有两件事:确保您在内部使用库的方式与用户使用库的方式相同。另外,它还确保您不要尝试从某个文件夹中测试代码,而是通过测试调用它。它“强制执行”的方式,也就是说,绝对导入不会从某个文件夹内部进行。而是需要通过外部文件/函数调用来调用它。