首頁  >  文章  >  後端開發  >  python模組查找的原理與方法介紹

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

巴扎黑
巴扎黑原創
2017-08-12 14:31:061506瀏覽

這篇文章主要給大家介紹了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.py
import os
import sys
print sys.path[0]
# execute
python test.py
python /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

<pre class="brush:py;">#ls ├── os.py ├── test2.py ├── redis.py #test2.py import os from redis import Redis #execute test2.py Traceback (most recent call last): File &quot;/Users/x/workspace/blog-code/p2016_05_28_python_path_find/test2.py&quot;, line 1, in &lt;module&gt; from redis import Redis ImportError: cannot import name Redis</pre>由於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])
&#39;/Users/x/workspace/blog-code&#39;
>>>

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

模組中的__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.py
print __file__
#相对路径执行
python test3.py
test3.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 &#39;__file__&#39; is not defined

這是因為目前互動式shell的執行並不是以檔案的形式加載,所以不存在_ _file__ 這樣的屬性。


sys.argv[0] 變數

#sys.argv[0] 就是它用來取得主入口執行檔。

#test.py
import sys
print __file__
print sys.argv[0]

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

#test.py
import sys
print __file__
print sys.argv[0]
#test2.py
import 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[&#39;tornado&#39;]
Traceback (most recent call last):
 File "<input>", line 1, in <module>
KeyError: &#39;tornado&#39;
>>> import tornado
>>> sys.modules[&#39;tornado&#39;]
<module &#39;tornado&#39; from &#39;/Users/x/python_dev/lib/python2.7/site-packages/tornado/__init__.pyc&#39;>
###前面說過 Python 解釋器啟動之後,會把預先載入 built-in module,可以透過 ###sys.modules ###驗證。 ############
>>> sys.modules[&#39;os&#39;]
<module &#39;os&#39; from &#39;/Users/x/python_dev/lib/python2.7/os.pyc&#39;>
>>>

借助 sys.modules 和 __file__,可以动态获取所有已加载模块目录和路径。


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


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

summary

总的来说,Python 是通过查找 sys.path 来决定包的导入,并且系统包优先级>同目录>sys.path,Python 中的特有属性 __file__ 以及 sys.argv[0]sys.modules 都能帮助我们理解包的查找和导入概念,只要能正确理解 sys.path 的作用和行为,理解包的查找就不是难题了。

以上是python模組查找的原理與方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn