一個小項目,需要用到包內模塊間調用,包外有文件又要調用包內模塊。
C:\USERS\XXX\DESKTOP\TEST
│ 1.py <===調用lib02.py所有屬性
│
└─lib
│ lib01.py
│ lib02.py <===調用lib01.py所有屬性,調用sublib.sublib02.py所有屬性
│
└─sublib
sublib01.py
sublib02.py <== 調用sublib01.py所有屬性
單純用import導入,一定會遇到要么1.py執行錯誤,要么包內lib02.py執行錯誤。
例如如下調用關系:
解決思路,方法1,2是失敗思路,方法3能解決問題但效率低,方法4嘗試但失敗。最有效的是方法5:
方法1、在目錄內增加空內容文件:__init__.py ------------>不能解決問題
如在sublib目錄下增加__init__.py文件,執行lib02.py會報錯:
1 Traceback (most recent call last): 2 File "C:\Users\xxx\Desktop\test\lib\lib02.py", line 1, in <module> 3 from sublib import sublib02 4 File "C:\Users\xxx\Desktop\test\lib\sublib\__init__.py", line 6, in <module> 5 import sublib01 6 ModuleNotFoundError: No module named 'sublib01'
方法2、在__init__.py增加import xxxx ------------>不能解決問題
如在sublib目錄下增加__init__.py文件中增加import sublib01、 import sublib02,執行lib02.py會報錯:同上
方法3、在每個__init__.py文件中使用代碼將當前目錄加入Python系統環境變量 ------------>解決問題,更完美方案其實是方法4,方法5
1 import os 2 import sys 3 rootpath = str(os.path.dirname(os.path.abspath(__file__))) 4 sys.path.append(rootpath)
總結:由於一直習慣使用Sublime Text 3寫點代碼,所以單純從import入手無法解決,需要借助環境變量解決問題。
另外如果使用PyCharm,該工具會自動在編譯執行時增加文件間調用關系,比純文本寫代碼方便一點,但還是不能完全解決問題。
感謝給我提供解決方案的同事:XKZ
經過1年多時間,又找到2個方法
方法4、虛擬環境activate文件加項目路徑
極客時間 Python核心技術與實戰 景霄 Facebook資深工程師 課程第13課提到的如下內容:
這里我稍微提一下 Python 的 Virtual Environment(虛擬運行環境)。Python 可以通過 Virtualenv 工具,非常方便地創建一個全新的 Python 運行環境。
在一個 Virtual Environment 里,你能找到一個文件叫 activate,在這個文件的末尾,填上下面的內容: export PYTHONPATH="/home/ubuntu/workspace/your_projects"
這樣,每次你通過 activate 激活這個運行時環境的時候,它就會自動將項目的根目錄添加到搜索路徑中去。
這個方法經過試驗有2個結論,1、在linux環境下也許更好用;2、我使用的python虛擬環境管理更方便的virtualenvwrapper-win以及sublime(不具備自動管理包之間關系能力)情況下,此方法無效。
方法5、site-packages目錄下增加 xxx.pth文件
我不甘心要在每個__init__.py都加環境變量修改腳本,查了資料,終於還是發現了另外一個比較一勞永逸的方法,只需要一次操作:
適用范圍:使用sublime,pycharm編寫在本機環境或【python虛擬環境virtualenvwrapper-win】運行的工程。
Python運行原理:python運行時都會先去site-packages目錄下尋找.pth文件,如果有就先加載里面的路徑到環境變量中。
在python環境(本機本土化或虛擬機環境 <-- 特別好用)如:D:\Python36\Lib\site-packages目錄下增加一個 xxx.pth文件,
.pth文件內容是要運行項目的絕對地址,windows操作系統記得使用 \\或\ 作為分隔符。
使用范例:我python工程目錄: E:\IapppayTest\Iapppay_SVN\Test\BKW\Python_Interface\IapppayBJ_INTF_V0.02
我在inftest.pth文件中應該如下書寫:E:\IapppayTest\Iapppay_SVN\Test\BKW\Python_Interface\IapppayBJ_INTF_V0.02
記得重啟編譯工具
注意:如果項目路徑中有中文,運行python編譯就會報錯:
解決辦法:1、把項目路徑換成英文;
2、修改python環境源碼 X:\Python36\lib\site.py的159行,由【f = open(fullname, "r")】修改為【f = open(fullname, "r",encoding='utf-8')】
為什么不是修改163行?因為在163行執行前的159行才是讀取文件的操作,這里的打開編碼格式直接影響了163行
大概就這樣解決了包引用的問題,由於沒有經過太多復雜調用,到目前為止都沒有出現問題,如果這個方法不好用,請留言。