[英]Local collection of Python packages: best way to import them?
我需要運送使用多個存儲在本地Library
目錄中的軟件包的Python程序集合 :目標是避免用戶在使用我的程序之前安裝軟件包(這些軟件包位於Library
目錄中)。 導入Library
包含的軟件包的最佳方法是什么?
我嘗試了三種方法,但它們都不是完美的:有沒有更簡單,更可靠的方法? 還是這些方法中最好的一種?
在第一種方法中,將Library
文件夾簡單地添加到庫路徑:
import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'Library')) import package_from_Library
Library
文件夾放在開頭,以便程序附帶的軟件包優先於用戶安裝的相同模塊(通過這種方式,我確定它們具有與我的程序一起使用的正確版本)。 當“ Library
文件夾不在當前目錄中時,此方法也適用。 但是,這種方法有缺點。 我的每個程序都向sys.path
添加相同路徑的副本,這很浪費。 此外,所有程序都必須包含相同的三條路徑修改行,這違反了“不要自己重復”的原則。
對上述問題的改進在於,通過在導入的模塊中添加Library
路徑,嘗試僅添加一次:
# In module add_Library_path: sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'Library'))
然后在我的每個程序中使用:
import add_Library_path import package_from_Library
這樣, add_Library_path
CPython的緩存機制,模塊add_Library_path
僅運行一次,並且Library
路徑僅添加一次到sys.path
。 但是,此方法的缺點是import add_Library_path
具有不可見的副作用,並且import add_Library_path
的順序很重要:這使代碼更不清晰,更脆弱。 另外,這迫使我分發程序以包含用戶不會使用的add_Library_path.py
程序。
也可以通過將它打包成一個包(存儲在其中的空__init__.py
文件)導入Library
Python 模塊 ,該包可以執行以下操作:
from Library import module_from_Library
但是,這會破壞Library
中的程序包 ,因為它們可能會執行from xlutils.filter import …
,這會中斷,因為在sys.path
找不到xlutils
。 因此,此方法有效,但僅當在Library
包含模塊而不是包中時才有效。
所有這些方法都有一些缺點。
有沒有更好的方法來傳送帶有存儲在本地Library
目錄中的程序包集合的程序? 還是上述方法之一(方法1?)是最好的方法?
PS :就我而言, Library
中的所有軟件包都是純Python軟件包,但是最好是適用於任何操作系統的更通用的解決方案。
PPS :目的是使用戶能夠使用我的程序而無需安裝任何程序(除了復制我定期發送的目錄之外),如上面的示例中所示。
PPPS :更准確地說,目標是要具有靈活性,使用戶對包含我的程序的目錄和“隱藏”的“ Library
文件夾進行簡單的復制 ,從而輕松地從“ Library
更新我的程序集及其相關的第三方程序包”第三方軟件包。 (我經常進行更新,因此我不想強迫用戶也更新他們的Python發行版。)
與sys.path()
混在一起會導致痛苦... 現代的程序包模板和Distribute包含大量信息,並且在某種程度上已設置為解決您的問題。
我要做的是設置setup.py,將所有程序包安裝到特定的站點程序包位置,或者將其安裝到系統的站點程序包中。 在前一種情況下,本地站點包將被添加到系統/用戶的PYTHONPATH中。 在后一種情況下,無需進行任何更改
您也可以使用批處理文件來設置python路徑。 或將python可執行文件更改為指向包含修改后的PYTHONPATH的shell腳本,然后執行python解釋器。 當然,后者意味着您必須有權訪問用戶的計算機,而您沒有權限。 但是,如果您的用戶僅運行腳本而不導入自己的庫,則可以使用自己的腳本包裝器:
#!/path/to/my/python
/path/to/my/python
腳本類似於:
#!/bin/sh
PYTHONPATH=/whatever/lib/path:$PYTHONPATH /usr/bin/python $*
我認為您應該看看路徑導入掛鈎 ,這些掛鈎可以在搜索模塊時修改python的行為。
例如,您可以嘗試像kde的scriptengine一樣為python插件[1]做一些事情。 它將一個特殊的令牌添加到sys.path
(例如"<plasmaXXXXXX>"
其中XXXXXX
是一個隨機數,以避免名稱沖突),然后當python嘗試導入模塊並且在其他路徑中找不到它們時,它將調用您的進口商可以處理。
一個更簡單的選擇是使用一個主腳本作為啟動器,該腳本僅將路徑添加到sys.path
並執行目標文件(這樣您就可以安全地避免在每個文件上放置sys.path.append(...)
行) 。
在python2.6 +上運行的另一種替代方法是將庫安裝在每用戶站點包目錄下。
[1]在使用kde的Linux安裝中,您可以在/usr/share/kde4/apps/plasma_scriptengine_python
下找到源代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.