分发命名空间包子模块
Distributing a namespace package submodules
我重新组织了我的 Python 项目,使其处于同名保护伞下。我的项目现在可以看作是可以相互依赖的多个子系统。这意味着每个子模块现在都可以单独分发,以便只安装必需的依赖项。
旧结构:
/
├─ myproj/
│ ├─ __init__.py
│ ├─ mod1.py
│ ├─ subpackage1/
│ └─ subpackage2/
└─ setup.py
新结构:
/
├─ myproj/
│ ├─ common/
│ │ └─ mod1.py
│ ├─ subpackage1/
│ └─ subpackage2/
└─ setup.py
如您所见,除了 myproj
现在是 namespace package 以及子包 common
、subpackage1
和 subpackage2
外,没有太大变化现在可以独立分发了。
是否可以在保留一个唯一的 setup.py
文件的情况下创建 3 个独立的包?
myproj.common
myproj.subpackage1
myproj.subpackage2
我还想说明一下,安装 myproj.subpackage1
时需要 myproj.common
,或者 myproj.subpackage2
需要 myproj.common
和 myproj.subpackage1
。
正如 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.
...
再一次,正如 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())
看来已经为您找到了一个好的解决方案。
我重新组织了我的 Python 项目,使其处于同名保护伞下。我的项目现在可以看作是可以相互依赖的多个子系统。这意味着每个子模块现在都可以单独分发,以便只安装必需的依赖项。
旧结构:
/
├─ myproj/
│ ├─ __init__.py
│ ├─ mod1.py
│ ├─ subpackage1/
│ └─ subpackage2/
└─ setup.py
新结构:
/
├─ myproj/
│ ├─ common/
│ │ └─ mod1.py
│ ├─ subpackage1/
│ └─ subpackage2/
└─ setup.py
如您所见,除了 myproj
现在是 namespace package 以及子包 common
、subpackage1
和 subpackage2
外,没有太大变化现在可以独立分发了。
是否可以在保留一个唯一的 setup.py
文件的情况下创建 3 个独立的包?
myproj.common
myproj.subpackage1
myproj.subpackage2
我还想说明一下,安装 myproj.subpackage1
时需要 myproj.common
,或者 myproj.subpackage2
需要 myproj.common
和 myproj.subpackage1
。
正如 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.
...
再一次,正如 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())
看来已经为您找到了一个好的解决方案。