2017-09-03 104 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