2017-09-03 53 views
0

我工作的一个Python库(不是我),看起来像这样:如何打包其导入在Python中产生副作用的库?

. 
├── README.md 
├── setup.py 
└── library 
    ├── __init__.py 
    ├── core.py 
    ├── a.py 
    └── b.py 

文件__init__.py化妆用其本身使用a.pyb.pycore.py。重要的是要注意import library有一些故意打算的副作用。

但是,我想给用户使用功能core.py而不会有任何副作用的可能性。遗憾的是,正如您所知,import library.corefrom library import core无论如何都会执行__init__.py(发生副作用)。

你知道我该如何重组我的包和setup.py来解决这个问题?


我认为是这样的:

. 
├── README.md 
├── setup.py 
├── library_core 
│ ├── __init__.py 
│ ├── core.py 
│ ├── a.py 
│ └── b.py 
└── library 
    └── __init__.py # Import library_core and apply side effects 

我将更新setup.pypackages = ['library', 'library_core']。这样,导入library不会改变任何内容,但用户可以导入library_core,而没有任何副作用。此外,这将避免重复代码,并且所有内容都会保留在同一个存储库中。

不幸的是,这不起作用,因为我无法从library导入library_core,因为它们不在文件树中的相同位置。

+0

*“不幸的是,这并不工作,因为我没有从库中导入library_core的能力。” * - 看起来像这是你的主要问题,当你在'library/__ init __。py'中尝试'从library_core import core'时会发生什么? – Kos

+0

@Kos其实,这可以工作...我首先试着'从..library_core import *'显然失败了,但只要'import library_core'将会工作**一旦安装了软件包**使用'python setup.py install'。我想这是要走的路。所以我会空白这个问题。 – Delgan

回答

0

使用两个包似乎是最好的方法。

仅当安装了整个库时,使用两个相邻的包才能使用(例如python setup.py install)。这使开发变得相当复杂,例如对于单元测试:因此无法执行import library,因为如果未安装,找不到library_core

因此,最好的解决方案是简单地制作一个子包装,并在setup.py内指定library_core的位置,这要归功于package_dir选件。

文件树是这样的:

. 
├── README.md 
├── setup.py 
└── library 
    ├── __init__.py 
    └── core 
     ├── __init__.py 
     ├── a.py 
     └── b.py 

而且在setup.py

setup(
    name = 'library', 
    packages = ['library', 'library.core', 'library_core'], 
    package_dir = {'library_core': 'library/core'}, 
    ... 
) 
0

我建议您停止依赖副作用,并要求用户通过调用一个文档化的函数明确触发它们。否则,你正在对抗一场失败的战斗:默认情况下是触发副作用,如果用户不需要它们,则必须撤消它们。

+0

这不是我的图书馆,它已经非常流行,所以我无法改变当前的行为。 – Delgan

+0

该规则的常见例外是polyfill库。比较和对比'from __future__ import absolute_import'。但是,这很不方便,例如flake8会抱怨“未使用”的进口产品 – Kos