分发命名空间包子模块

Spa*_*ack 5 python setuptools namespace-package

我已经将我的 Python 项目重新组织到同名的保护伞下。我的项目现在可以被视为多个可以相互依赖的子系统。这意味着每个子模块现在都可以单独分发,以便仅安装所需的依赖项。

\n\n

旧结构:

\n\n
/\n\xe2\x94\x9c\xe2\x94\x80 myproj/\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 __init__.py\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 mod1.py\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 subpackage1/\n\xe2\x94\x82  \xe2\x94\x94\xe2\x94\x80 subpackage2/\n\xe2\x94\x94\xe2\x94\x80 setup.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

新结构:

\n\n
/\n\xe2\x94\x9c\xe2\x94\x80 myproj/\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 common/ \n\xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x94\xe2\x94\x80 mod1.py\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 subpackage1/\n\xe2\x94\x82  \xe2\x94\x94\xe2\x94\x80 subpackage2/\n\xe2\x94\x94\xe2\x94\x80 setup.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

myproj正如您所看到的,除了现在是命名空间包和子包之外,没有太大变化commonsubpackage1并且subpackage2现在可以独立分发。

\n\n

有没有可能,仍然保留一个独一无二的setup.py文件的情况下创建 3 个独立的包?

\n\n
    \n
  • myproj.common
  • \n
  • myproj.subpackage1
  • \n
  • myproj.subpackage2
  • \n
\n\n

另外我想指定安装时myproj.subpackage1myproj.common是必需的,或者myproj.subpackage2需要myproj.common同时myproj.subpackage1

\n

jus*_*gel 2

正如 Martijn Pieters 所说,这只是 python 代码,所以是的,你可以做到这一点。我什至认为这也不会那么困难。

基本上你只想操作 setup.py 中的命令行参数

import sys

if sys.argv[1] == "subpackage1":
    # Remove the first command line argument so the setup function works normally.
    sys.argv.pop(1)

    # Run setup code for subpackage1 or 
    # Use a separate setup file and call "import setup_subpackage1"
    ...
elif sys.argv[1] == "subpackage2":
    # Remove the first command line argument so the setup function works normally.
    sys.argv.pop(1)

    # Run setup code for subpackage2 or
    # Use a separate setup file and call "import setup_subpackage2"
    ...
else:
    # Check if they gave common as an argument or just left if blank
    if sys.argv[1] == "common":
        # Remove the first command line argument so the setup function works normally.
        sys.argv.pop(1)

    # Run setup code for both packages.
    ...
Run Code Online (Sandbox Code Playgroud)

但正如 Martijn Pieters 所说,这可能不值得付出努力。Python 的主要哲学是简单胜于复杂。如果您的两个子包完全不同,那么它们可能应该是不同的项目。

示例:Scipy

我试图想一个例子来说明为什么不这样做,但显然scipy这样做了。所以我试图劝阻你可能是错误的。仍然可能不值得付出努力,因为大多数人只是pip install scipy

这真有趣。Scipy 的结构经过深思熟虑。Scipy 将每个子包都作为 Python 包(带有 __init__.py 文件的目录)。每个包的内部都有一个 setup.py 文件。它们还用于numpy.distutils.misc_util.Configuration添加子包。

如果你查看他们的源代码,scipy 的主 setup.py 文件看起来像这样。

from __future__ import division, print_function, absolute_import

import sys


def configuration(parent_package='',top_path=None):
    from numpy.distutils.misc_util import Configuration
    config = Configuration('scipy',parent_package,top_path)
    config.add_subpackage('cluster')
    config.add_subpackage('constants')
    config.add_subpackage('fftpack')
    config.add_subpackage('integrate')
    config.add_subpackage('interpolate')
    config.add_subpackage('io')
    config.add_subpackage('linalg')
    config.add_data_files('*.pxd')
    config.add_subpackage('misc')
    config.add_subpackage('odr')
    config.add_subpackage('optimize')
    config.add_subpackage('signal')
    config.add_subpackage('sparse')
    config.add_subpackage('spatial')
    config.add_subpackage('special')
    config.add_subpackage('stats')
    config.add_subpackage('ndimage')
    config.add_subpackage('_build_utils')
    config.add_subpackage('_lib')
    config.make_config_py()
    return config

if __name__ == '__main__':
    from numpy.distutils.core import setup
    setup(**configuration(top_path='').todict())
Run Code Online (Sandbox Code Playgroud)

所以看来已经为您找到了一个好的解决方案。