python模組尋找的原理與方法介紹

來源:互聯網
上載者:User
這篇文章主要給大家介紹了python中模組尋找的原理與方式,文中通過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。

前言

本文主要給大家介紹了關於python模組尋找的原理與方式,分享出來供大家參考學習,下面話不多說,來一起看看詳細的介紹:

基礎概念

module

模組, 一個 py 檔案或以其他檔案形式存在的可被匯入的就是一個模組

package

包,包含有 __init__ 檔案的檔案夾

relative path

相對路徑,相對於某個目錄的路徑

absolute path

絕對路徑,全路徑

路徑尋找

python 解譯器尋找被引入的包或模組

Python 解譯器是如何尋找包和模組的

Python 執行一個 py 檔案,無論執行的方式是用絕對路徑還是相對路徑,interpreter 都會把檔案所在的 directory 加入 sys.path 這個 list 中,Python 就是在 sys.path 中尋找包和模組的,sys.path 中的內容本身又是又 Python 的環境變數決定。

code-1


#test.pyimport osimport sysprint sys.path[0]# executepython test.pypython /Users/x/workspace/blog-code/p2016_05_28_python_path_find/test.py

執行表明相對路徑和絕對路徑都輸出相同的結果,而且無論哪種執行方式,test.py 所在的檔案夾都會被加入 sys.path 的首位,也就是索引為0的位置。

Python 解譯器尋找包的順序是什麼

解譯器尋找包,首先搜尋 built-in module,其次搜尋 sys.path ,這樣的尋找順序將會導致同名包或模組被遮蔽。

code-2


#ls├── os.py├── test2.py├── redis.py#test2.pyimport osfrom redis import Redis#execute test2.pyTraceback (most recent call last): File "/Users/x/workspace/blog-code/p2016_05_28_python_path_find/test2.py", line 1, in <module> from redis import RedisImportError: cannot import name Redis

由於 os 是 built-in module,即使在同目錄下有同名模組,解譯器依然可以找到正確的 os 模組,可以證實 built-in module 不會被遮蔽,而 redis 屬於第三方模組,預設安裝位置是 Python 環境變數中的 site-packages,解譯器啟動之後會將此目錄中的內容加入 sys.path,由於目前的目錄會在 sys.path 的首位,目前的目錄的 redis 優先被找到,site-packages 中的 redis 模組被遮蔽了。

互動式執行環境的尋找順序

進入互動式執行環境,解譯器會自動把目前的目錄加入 sys.path, 這時目前的目錄是以相對路徑的形式出現在 sys.path 中:


>>> import os.path>>> import sys>>> os.path.abspath(sys.path[0])'/Users/x/workspace/blog-code'>>>

除此之外,其他與執行一個檔案是相同的。

模組中的 __file__ 變數

__file__ is the pathname of the file from which the module was loaded, if it was loaded from a file. 如果一個模組是從檔案載入的,__file__ 就是該模組的路徑名–Python Doc:

顧名思義,當模組以檔案的形式出現 __file__ 指的是模組檔案的路徑名,以相對路徑執行 __file__ 是相對路徑,以絕對路徑執行 __file__ 是絕對路徑。


#test3.pyprint __file__#相對路徑執行python test3.pytest3.py#絕對路徑執行python /Users/x/workspace/blog-code/p2016_05_28_python_path_find/test3.py/Users/x/workspace/blog-code/p2016_05_28_python_path_find/test3.py

為了保證__file__ 每次都能準確得到模組的正確位置,最好對其再取一次絕對路徑 os.path.abspath(__file__)

互動式 shell 中的 __file__


>>> __file__Traceback (most recent call last): File "<input>", line 1, in <module>NameError: name '__file__' is not defined

這是因為當前互動式shell的執行並不是以檔案的形式載入,所以不存在__file__ 這樣的屬性。

sys.argv[0] 變數

sys.argv[0] 是它用來擷取主入口執行檔案。


#test.pyimport sysprint __file__print sys.argv[0]

以上 print 輸出相同的結果,因為主執行檔案和__file__所屬的模組是同一個,當我們改變入口檔案,區別就出現了。


#test.pyimport sysprint __file__print sys.argv[0]#test2.pyimport test#execute test2.py/Users/x/workspace/blog-code/p2016_05_28_python_path_find/child/test.py #__file__test2.py #sys.argv[0]

總的來說,sys.argv[0] 是獲得入口執行檔案路徑,__file__ 是獲得任意模組檔案的路徑。

sys.modules 的作用

既然 Python 是在 sys.path 中搜尋模組的,那載入的模組存放在何處?答案就是 sys.modules。模組一經載入,Python 會把這個模組加入 sys.modules 中供下次載入使用,這樣可以加速模組的引入,起到緩衝的作用。


>>> import sys>>> sys.modules['tornado']Traceback (most recent call last): File "<input>", line 1, in <module>KeyError: 'tornado'>>> import tornado>>> sys.modules['tornado']<module 'tornado' from '/Users/x/python_dev/lib/python2.7/site-packages/tornado/__init__.pyc'>

前面說過 Python 解譯器啟動之後,會把預先載入 built-in module,可以通過 sys.modules 驗證。


>>> sys.modules['os']<module 'os' from '/Users/x/python_dev/lib/python2.7/os.pyc'>>>>

藉助 sys.modules 和 __file__,可以動態擷取所有已載入模組目錄和路徑。


>>> import os>>> os.path.realpath(sys.modules['os'].__file__)'/Users/x/python_dev/lib/python2.7/os.pyc'>>> import tornado>>> os.path.realpath(sys.modules['tornado'].__file__)'/Users/x/python_dev/lib/python2.7/site-packages/tornado/__init__.pyc'


def get_module_dir(name): path = getattr(sys.modules[name], '__file__', None) if not path raise AttributeError('module %s has not attribute __file__'%name) return os.path.dirname(os.path.abspath(path))

summary

總的來說,Python 是通過尋找 sys.path 來決定包的匯入,並且系統包優先順序>同目錄>sys.path,Python 中的特有屬性 __file__ 以及 sys.argv[0]sys.modules 都能協助我們理解包的尋找和匯入概念,只要能正確理解 sys.path 的作用和行為,理解包的尋找就不是難題了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.