【筆記13】完美解決了!關於python的相對導入和絕對導入


最近在學習別人寫的程序,有位大神把其他經典算法都實現了,baseline包全弄好了,我真是興沖沖,提起袖子膜拜大神,沒想到環境都build好了,在引自己的各種模塊時頻頻報錯,深知是引用的問題,Google了半天都沒弄好,最後經過耐心探索在不小心把自己的.bashrc環境刪掉還重配了conda之後,總結了怎麼解決引用問題的方法。

解決方案

先把出現報錯的解決方案放在前面:
檢查哪種錯誤:

ValueError: Attempted relative import in non-package
說明存在相對導入語句的模塊,不能直接運行,把相對導入改成絕對引用。

No module named ‘…’
說明路徑不對,找不到模塊。

如果是絕對導入,一個模塊只能導入自身的子模塊或和它的頂層模塊同級別的模塊及其子模塊
如果是相對導入,一個模塊必須有包結構且只能導入它的頂層模塊內部的模塊

  1. 找不到模塊時,先看看有沒有__init__.py文件在該包裏,告訴導入指令我包在這。
  2. 如果要把相對導入改爲絕對導入,from __future__ import absolute_import(僅禁用隱式相對導入),Python2.x 缺省爲相對路徑導入,Python3.x 缺省爲絕對路徑導入。
  3. 萬能法。直接把該文件夾看作一個workspace,路徑加入環境變量中。(這裏考慮加入用戶的環境變量,而不是全局的系統變量),在用戶home路徑下可以看是否有這個隱藏文件ls -a,~表示用戶home目錄。
    vim ~/.bash_profile
    進入vim編輯器,隨意i\o\a進入編輯模式
    export PYTHONPATH=</home/user/ALL>:$PATH
    這裏的<>替換成該文件夾地址,然後加上:$PATH表示這個PATH爲該地址再加上原來路徑,最後不要加/。
    source ~/.bash_profile
    原理是會在PYTHONPATH的List依次搜索,如果在前面搜到就用前面的模塊,而不會繼續向下,這樣自定義模塊優先。
  4. 治標不治本法1。在代碼裏將當前模塊路徑加入,腳本退出失效。
    import sys
    sys.path.append('/home/user/ALL/')
  5. 治標不治本法2。直接export PYTHONPATH=</home/user/ALL>:$PATH,但是終端關閉就失效。

import的搜索路徑

導入分爲相對導入和絕對導入,而這個導入是有原則的。

  • 當前目錄下搜索import的模塊
  • 在環境變量PYTHONPATH的List依次搜索
  • 在python安裝路徑的lib裏搜索

相對導入和絕對導入

相對是對於當前目錄而言的,先牢記.代表當前模塊,..代表上層模塊,...代表上上層模塊,比如以下結構:

ALL
|___A
|	|___Z
|		|___util.py
|		|___init.py
|___B
|	|__check.py
|___C
|	|___result.py
|___setup.py
  • A B C文件夾和setup.py文件都在ALL
  • ZA裏,util.pyinit.pyZ
  • check.pyB
  • resul.pyC

這一篇寫得很詳細Python 相對導入與絕對導入

相對導入

  • util.py裏導入init.py可以寫爲
    • import init(不用加.因爲會先在當前目錄下搜索)
    • from . import init
    • from Z import init
  • util.py裏導入check.py可以寫爲from ..B import check

絕對導入

  • util.py裏導入init.py寫爲 import ALL.A.Z imprort init
  • util.py裏導入check.py可以寫爲from ALL.B import check
    • util.py裏導入setup.py可以寫爲from ALL import check
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章