简体   繁体   English

分发命名空间包子模块

[英]Distributing a namespace package submodules

I've reorganized my Python project to be under a same name umbrella. 我已经将我的Python项目重组为同名伞。 My project can now be seen as multiple subsystems than can depend on each other. 我的项目现在可以看作是多个子系统而不是相互依赖。 That means that every submodule can now be distributed alone so that only required dependencies can be installed. 这意味着现在可以单独分发每个子模块,以便只安装所需的依赖项。

The old structure: 旧结构:

/
├─ myproj/
│  ├─ __init__.py
│  ├─ mod1.py
│  ├─ subpackage1/
│  └─ subpackage2/
└─ setup.py

The new structure: 新结构:

/
├─ myproj/
│  ├─ common/ 
│  │  └─ mod1.py
│  ├─ subpackage1/
│  └─ subpackage2/
└─ setup.py

As you can see not much has changed except that myproj is now a namespace package and that sub-packages common , subpackage1 and subpackage2 can now be distributed independently. 正如您所看到的那样,除了myproj现在是命名空间包并且子包common之外没有太多变化,现在可以独立分发subpackage1subpackage2

Is it possible, still keeping one unique setup.py file, to create 3 independent packages? 是否仍然可以保留一个唯一的setup.py文件来创建3个独立的包?

  • myproj.common
  • myproj.subpackage1
  • myproj.subpackage2

Also I'd like to specify that when installing myproj.subpackage1 , myproj.common is required or that myproj.subpackage2 will require both myproj.common and myproj.subpackage1 . 另外我想指定在安装myproj.subpackage1myproj.common是必需的,或myproj.subpackage2需要myproj.commonmyproj.subpackage1

As Martijn Pieters stated it is just python code, so yes you can do this. 正如Martijn Pieters所说,它只是python代码,所以是的,你可以做到这一点。 I don't even think this would be all that difficult either. 我甚至认为这也不会那么困难。

Basically you just want to manipulate the command line arguments in setup.py 基本上你只想操作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.
    ...

Once again though as Martijn Pieters stated it is probably not worth the effort. 虽然Martijn Pieters表示这可能不值得努力。 Python's main philosophy is that simple is better than complex. Python的主要哲学是简单比复杂更好。 If your two sub-packages are completely different then maybe they should be different projects. 如果你的两个子包完全不同,那么它们应该是不同的项目。

Example: Scipy 示例:Scipy

I tried to think of an example for why not to do this, but apparently scipy does this. 我试图想出一个为什么不这样做的例子,但显然scipy这样做。 So I may be wrong in trying to dissuade you. 所以我试图劝阻你可能是错的。 Still probably not worth the effort, because most people just pip install scipy . 仍然可能不值得努力,因为大多数人只是pip install scipy

It's interesting. 这真有趣。 Scipy's structure is very well thought out. Scipy的结构经过深思熟虑。 Scipy has every sub-package as a Python package (directory with an __init__.py file.). Scipy将每个子包都作为Python包(带有__init__.py文件的目录)。 Inside of every package is a setup.py file. 每个包里面都有一个setup.py文件。 They also use numpy.distutils.misc_util.Configuration to add sub packages. 他们还使用numpy.distutils.misc_util.Configuration添加子包。

If you look through their source code, scipy's main setup.py file looks like. 如果你查看他们的源代码,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())

So it looks like a good solution has already been found for you. 所以看起来已经找到了一个很好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM