2018年10月5日python相對引入和絕對引入詳解
|-direct
|-plane
|-__init__.py
|-modules.py
|-tools.py
|-tank
main.py
utils.py
main.py:
# 在自身資料夾下import 引入其他模組
import utils
# 引入其他包中的某個模組
import plane.tools
# 直接import的方式可以引入包,可以引入模組,最低階就是引入模組級別的檔案,不能使用import方式直接匯入模組中的變數,函式,型別,因為import方式它會把最後一個當成模組級別的檔案來判斷,結果就找不到這個對應的模組了,下面這種方式就是錯誤的方式
import plane.tools.hello_vars
使用import方式引入相應的模組之後,可以使用如下的方式操作引入的模組中的資料:
模組.變數
模組.函式
模組.型別
|-direct
|-main.py
|-utils.py
main.py:
# 直接引入的方式,
import utils
使用Import的方式尋找引入模組的路徑是(所有絕對引入的查詢路徑):
1. 在當前資料夾,也就是direct(常用就是第一種)
2. 在環境變數PYTHONPATH指定的資料夾中的查詢utils.py(很少去配置)
3. 在Python 直譯器sys.path指定的資料夾中查詢utils.py(很少去設定)
# 相對路徑引入
from . import utils
print(utils.msg)
相對引入的方式沒有錯,但是如果直接執行的話就會報錯:
ImportError: cannot import name ‘utils’
因為如果當前模組直接執行的話Python直譯器就會認為當前模組就是頂層模組,是唯一一個,就不存在相對引入的說法了,所以如果檔案中存在相對引入的話要想執行不報錯,不能直接執行,必須給當前模組找一個檔案中相對引入的參照物,例如在pycharm終端裡面輸入命令: python -m direct.mian
就能正常運行了,因為檔案中的相對引入方式的參照物就是direct這個資料夾。-m是指定的意思。
import直接引入和from x import …引入的區別就是Impot直接引入的方式可以引入包,可以引入模組,最低也要引入模組級別的檔案,而用from x import…方式引入的話可以引入比較細緻的的變數,函式,型別
|-direct
|-main.py
|-utils.py
main.py:
# 引入一個細緻的變數/函式/型別
from .utils import msg
print(msg)
執行命令是在pycharm終端中輸入: python -m direct.main
包和普通資料夾的區別:
包中一定要有一個__init__包宣告檔案
如何建立一個包:
可以在pycharm中右鍵->new->python package.
也可以先建立一個普通資料夾,然後在該資料夾中建立一個名為__init__.py的檔案,那個這個普通資料夾就變成了一個包了
————————————————————————————————————————————-————————
相對引入和絕對引入
絕對匯入的格式為 import A.B 或 from A import B
相對匯入格式為 from . import B 或 from ..A import B,.代表當前模組,..代表上層模組,...代表上上層模組,依次類推)
相對引入的方式程式碼不能直接執行,會報錯,前面有詳解,必須給當前模組找一個檔案中相對引入的參照物,例如在pycharm終端裡面輸入命令: python -m direct.mian 才能正常執行
|-direct
|-plane
|-__init__.py
|- utils.py
main.py
main.py:
相對引入:
- 相對引入引入整個包,這個比較特殊,必須在包的__init__檔案中定義其他檔案引入該包要用到的東西。(個人理解:python對直接以相對方式引入整個包的這樣方式不太贊同,因為如果包很大,裡面內容很多的話就會拖慢引用者的執行速度,導致使用者體驗差,為了提高使用者對pyhton的體驗感,所以python 加了這樣一個設定。可以理解!同時也給我們提醒,最好不要以相對的方式直接引入整個包,那樣你還要在__init__.py中定義你要用到的該包中的哪些內容,比較麻煩,還不如你直接引用的時候就指定使用包中的哪個模組或者哪個模組的哪個變數/函式/型別,還方便還不需要在包的__init__.py檔案中定義任何東西)
使用相對引入的方式直接引入包plane的話引入的是該包宣告檔案__init__.py中的程式碼,所以要在__init__中定義你要使用的這個包的哪些資料。
main.py:
from . import plane
print(plane.name)
print(plane.utils.msg)
備註:
切記不要在包宣告檔案__init__.py中沒有定義任何程式碼的情況下,通過包名稱操作包中的模組程式碼,那樣會報錯,報錯圖片如下,一定要先在引入的包的__init__.py宣告檔案中定義你要進行的包模組操作,相對方式引入的包才能正常工作。
下面兩種相對引入方式不需要在包的__init__中定義任何東西就可以使用引入的包內的資料,在pycharm終端中使用命令 : python -m direct.main執行
- 相對引入引入包中的模組
引入包內的模組不能使用from . import plane.utils, 這樣後半部分會報錯,要把包名稱寫在前面,如:
from .plane import utils
print(utils.msg)
- 相對引入引入包中的模組中的具體程式碼方法/函式/型別
from .plane.utils import func
func()
——————————————————————————————————————————————————————
絕對引入:
main.py:
- 最直接的絕對引入整個包(但是同樣引入整個包和相對引入整個包一樣需要在該包的__init__.py中定義要使用包中的哪些資料,後邊才能正常使用引入的包,否則會報錯找不到包下的那個模組)。
import plane
print(plane.utils.msg)
絕對方式引入包中的模組或者具體資料就不需要在該包的__init__.py宣告檔案定義任何東西就可以使用包中的資料
- 絕對引入的方式引入包中的模組
from plane import utils
3. 絕對引入的方式引入包中的模組的具體資料
from plane.utils import msg
print(utils.msg)
print(msg)
——————————————————————————————————————————————————
無論是相對引入和絕對引入,使用from a import b的最後的位置都是隻有一個模組名或者具體資料名,如果有多個字首都要放到前邊的from中。
可以給引入的名稱比較長的模組路徑起一個別名,例如:
import plane.utils as pu
還有一種引入的方式,模糊引入:
from 包名稱 import *
這是一個語法糖,慎重使用
如果專案中需要引入的包檔案不多的話, 可以參考使用
如果專案中需要引入的包檔案非常龐大,不要使用模糊引入,會嚴重消耗系統資源
同時使用模糊引入的話需要在引入的包中的宣告檔案__init__中定義*所包括本包下的哪些模組。這時有一個模組定義屬性: __all__, 值是一個列表,表示通過模糊引入方式直接匯入all中定義的所有模組,是寫在包的__init__宣告檔案中的,例如:
__all__ = [“utils”, “modules”, “tools”], 意思就是通過模糊引入的方式,直接可以引入包中的哪些模組,直接定義在__all__中就可以了
整合開發環境(IDE,Integrated Development Environment )是用於提供程式開發環境的應用程式也就是程式開發工具。
IDLE 是一個純 Python 下自帶的簡潔的整合開發環境(IDE) [1] 。
——————————————————————————————————————————————————————
小總結
1. 模組和包
模組:python中每個python檔案都是一個獨立的模組
較少的、獨立的、功能近似的 多個變數、函式、型別的集合!
包:包含多個python模組的資料夾,包含一個特殊的__init__.py宣告檔案
包含多個模組,具備強大功能的程式!
包 & 資料夾 區別
包:包含了一個__init__.py宣告檔案[空檔案、編寫程式碼]
資料夾:普通資料夾
區別1:包可以更加有效的管理python模組,資料夾只能作為預設包進行基本管理[包含檔案]!
區別2:包和資料夾中引入對應的模組程式碼的操作方式區別!
2. import & from import
包和模組的引入
(1) import
#引入一個模組
import 模組名稱
#使用模組中的資料
模組名稱.變數名稱
模組名稱.函式名稱
模組名稱.型別名稱
# 引入一個包
import 包名稱
# 使用包中的資料
包名稱.模組名稱.變數名稱/函式名稱/型別名稱
# 引入包中的某個模組
import 包名稱.模組名稱
# 使用包中的資料
包名稱.模組名稱.變數名稱/函式名稱/型別名稱
# ERROR:引入包中的某個變數
import 包名稱.模組名稱.變數名稱
(2) from import語法
# (相對)引入包
from . import 包名稱 [必須在__init__.py中,主動通過from . import引入需要的模組]
# 使用資料
包名稱.模組名稱.變數名稱/函式名稱/型別名稱
# (相對)引入包中的模組
from .包名稱 import 模組名稱
# 使用資料
模組名稱.變數名稱/函式名稱/型別名稱
# (相對) 引入包中的模組中的資料
from .包名稱.模組名稱 import 變數/函式/型別
# 使用資料:當成當前檔案中的資料進行資料
變數名稱/函式名稱/型別名稱
3. 相對引入 & 絕對引入
相對引入:相對當前檔案路徑,參照父級檔案路徑
|-- demo/
|-- utils.py
|-- main.py [from . import utils]
執行:新增參照路徑:python -m demo.main
執行過程中,在main.py中找到相對路徑的utils.py
絕對引入:針對包/專案/模組,直接引入的方式
|-- demo/
|-- users/
|-- __init__.py
|-- tools.py
|-- utils.py
|- main.py
[import utils]
[from users import tools]
[絕對引入:查詢路徑]
[當前資料夾|PYTHONPATH|sys.path]