Python筆記--import

首先要理解python裏模塊和包的概念:
* 模塊(module):擴展名爲.py的文件
* 包(package):含有模塊的文件夾,在python2裏,包含__init__.py的文件夾。

當模塊(module)中的代碼需要訪問另一個模塊(module)或包(package)的時候,需要導入(import)模塊(module)或包(package)

Python的導入流程:

以導入模塊abc爲例:
首先Python會在sys.modules中找該模塊名,sys.modules是之前導入的所有模塊的緩存
如果在緩存中沒有找到,Python會在內置模塊中查找,這些模塊都可以在Python Standard Library中找到。
如果依然沒有找到,Python會在sys.path中查找,即在系統的環境變量中查找,通常會包含當前文件夾,並且當前文件夾會第一個被查找。
當python找到模塊時,它將其綁定到本地作用域中。這樣abc就會被定義並且被當前文件使用而不會報錯。

Import的兩種形式:

直接導入資源:

import abc

其中,abc可以是一個包或者是一個模塊

從另一個模塊或包中導入資源:

from xyz import abc

其中,xyz可以是模塊、子包、對象(類、函數)
如果將abc換成*,即意爲導入xyz下的所有資源,這種調用通常很少用
在xyz下的__init__.py中,使用__all__ 可以定義*導入的資源(可以自己嘗試一下)

在導入過程中,可以對導入的資源重新命名。
如:

import abc as rename

此時,必須使用rename進行引用,使用abc會無法識別

導入的樣式(佈局)

一般情況下,導入的資源分爲三類:
標準庫導入,Python的內置模塊
關聯的第三方導入,模塊不屬於當前應用項目但是已經被裝載
本地應用導入,模塊屬於當前應用項目
所以在書寫時,可以根據這三類,進行分類,同時根據字母進行排序,增加可讀性

Import還有兩個比較有用的小知識點

  1. 如果package文件夾下包含__init__.py模塊,導入package時會先執行__init__.py代碼
  2. 所有模塊只會被導入一次

絕對導入和相對導入

絕對導入(Absolute Imports)

指定從項目根文件夾中使用其完整路徑導入的資源。
比如一個項目的目錄結構如下:
└── project
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── init.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
project包含兩個子包:package1和package2,
package1裏包含了兩個模塊:module1.py和module2.py
package2裏包含了三個模塊和一個子包:init.py、module3.py、module4.py和subpackage1
subpackage1裏包含了一個模塊:module5.py
現在假設:

  1. package1/module2.py包含一個函數function1.
  2. package2/init.py包含一個類class1.
  3. package2/subpackage1/module5.py包含一個函數function2.
from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2

絕對導入需要給出從頂級包開始的完整路徑
絕對導入的利弊:
清晰且直接,可以很容易看出導入的資源所在位置
但是當目錄結構過於複雜時,會顯得特別的冗長

相對導入(Relative Imports)

指定要相對於當前位置(即import語句所在的位置)導入的資源。相對導入有兩種類型:隱式和顯式。在python 3中,隱式相對導入已被棄用,就不聊隱式了。
相對導入的形式:

from .some_module import some_class
from ..some_package import some_function
from . import some_class

相對導入使用點標記來指定位置。
單點 . 意味着引用的模塊或包位於與當前位置相同的目錄中。
兩點 … 表示它在當前位置的父目錄中,即上面的目錄中。
三個點 … 表示它在祖父母目錄中,以此類推。

# package1/module1.py
from .module2 import function1
# package2/module3.py
from . import class1
from .subpackage1.module5 import function2

相對導入可能會很混亂,特別是對於目錄結構可能更改的共享項目。相對導入也不像絕對的一樣具有很好的可讀性,而且很難分辨導入資源的位置。

測試程序

爲了便於理解,我寫了測試程序放在了Github上。推薦使用debug模式運行代碼,這樣可以看清楚程序具體執行過程。項目目錄和上邊的例子不同
下載地址:https://github.com/TianHY1988/ImportTestInPython.git.
如果有任何疑問、建議或者有相關問題的討論,歡迎留言或者直接給我email:[email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章