這篇文章主要給大家介紹了python中模組查找的原理與方式,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。
前言
本文主要介紹了關於python模組查找的原理與方式,分享出來供大家參考學習,下面話不多說,來一起看看詳細的介紹:
基礎概念
module
模組, 一個py 檔案或以其他檔案形式存在的可被導入的就是一個模組
package
包,包含有__init__ 檔案的文件夾relative path
相對路徑,相對於某個目錄的路徑絕對路徑,全路徑
路徑查找
python 解釋器會尋找被引入的套件或模組
Python 解釋器是如何尋找套件和模組的
Python 執行一個py 文件,無論執行的方式是用絕對路徑還是相對路徑,interpreter 都會把文件所在的directory 加入sys.path 這個list 中,Python 就是在sys.path 中找尋套件和模組的,
sys.path
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
Python 解釋器查找包的順序是什麼
#解釋器查找包,首先搜尋built-in module,其次搜尋sys.path ,這樣的查找順序將會導致同名套件或模組被遮蔽。
<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 "/Users/x/workspace/blog-code/p2016_05_28_python_path_find/test2.py", line 1, in <module>
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
, 這時目前目錄是以相對路徑的形式出現在
中:
##
>>> import os.path >>> import sys >>> os.path.abspath(sys.path[0]) '/Users/x/workspace/blog-code' >>>除此之外,其他與執行一個檔案是相同的。
顧名思義,當模組以檔案的形式出現__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
。 互動式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] 就是它用來取得主入口執行檔。
#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 是在
>>> 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
的作用和行为,理解包的查找就不是难题了。
以上是python模組查找的原理與方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!