#秉著python一切皆為物件的原則,我來看看python庫的型別
import os
print
(type
(os)
)# 結果為乙個名為'module'的型別
#1、什麼樣的檔案型別叫做模組
#以.py檔案結尾的都可以被python認為是模組
#2、package的概念
#為了幫助組織模組並提供名稱層次結構,python 還引入了包的概念
#通常以乙個包含 __init__.py 檔案的目錄形式實現。 當乙個正規包被匯入時,
#這個 __init__.py 檔案會隱式地被執行,它所定義的物件會被繫結到該包命名空間中的名稱。__init__.py
#檔案可以包含與任何其他模組中所包含的 python **相似的**,python 將在模組被匯入時為其新增額外的屬性。
#值得注意的是,當模組被正確載入的時候模組會被解析成module物件,所謂的新增額外屬性也就是在型別的屬性命名空間
#__dict__新增,python中很多物件屬性的管理都是動態新增的
#要注意的乙個重點概念是所有包都是模組,但並非所有模組都是包。或者換句話說,包只是一種特殊的模組。
#特別地,任何具有 __path__ 屬性的模組都會被當作是包。
import logging #我們拿logging來舉例,準確來講logging是乙個包,它的目錄下包含了多個模組,按照上述,包可以看做一種特殊的模組
print
(logging.__loader__.is_package(
'logging'))
#通過包載入器來判斷是否為乙個包,當然我們可以通過模組的特殊屬性來判斷
print
(logging.__name__)
#限定名稱如果為頂層包,則直接反饋包名,否則將以'.'的形式呈現路徑結構
from logging import config
print
(config.__name__)
#logging.config
print
(logging.__package__)
#logging
print
(logging.__file__)
#d:\python3\lib\logging\__init__.py 如果為包則反饋包下__init__.py檔案的路徑,此檔案會在包被匯入時執行
print
(config.__file__)
#模組的檔案路徑
print
(config.__path__)
#報錯了,模組沒有__path__屬性,而包則必須包含此屬性,因此我們可以通過判斷此屬性來卻別模組與包 '__path__' in config.__dict__ ?
print
(logging.__path__)
#3、匯入相關的模組屬性
#__name__¶
#__name__ 屬性必須被設為模組的完整限定名稱。 此名稱被用來在匯入系統中唯一地標識模組。
#fullname 限定名稱的定義
#參照官方文件的定義: 乙個以點號分隔的名稱,顯示從模組的全域性作用域到該模組中定義的某個類、函式或方法的「路徑」
#__loader__
#__loader__ 屬性必須被設為匯入系統在載入模組時使用的載入器物件
#__package__
#模組的 __package__ 屬性必須設定。 其取值必須為乙個字串,但可以與 __name__ 取相同的值。當模組是包時,其__package__ 值應該設為其 __name__ 值。
#當模組不是包時,對於最高層級模組 __package__ 應該設為空字串,對於子模組則應該設為其父包名
#__spec__
#__spec__ 屬性必須設為在匯入模組時要使用的模組規格說明。 對 __spec__ 的正確設定將同時作用於 直譯器啟動期間初始化的模組
#__path__
#如果模組為包(不論是正規包還是命名空間包),則必須設定模組物件的 __path__ 屬性
#不是包的模組不應該具有 __path__ 屬性。
#__file__
#包或模組的檔案路徑,當為包是路徑為__init__.py檔案的路徑,當為模組時,則為模組的路徑
#4、模組載入過程
#官方提供的載入過程實現原始碼
'''module = none
if spec.loader is not none and hasattr(spec.loader, 'create_module'):
# it is assumed 'exec_module' will also be defined on the loader.
module = spec.loader.create_module(spec)
if module is none:
module = moduletype(spec.name)
#這裡我可以通過types模組來引入moduletype來建立模組,但是通常不這樣做
#通過會根據spec來建立模組,因為這樣可以在模組上設定更多的特有屬性
#可以通過importlib.util.module_from_spec() 來實現
# the import-related module attributes get set here:
_init_module_attrs(spec, module)
if spec.loader is none:
if spec.submodule_search_locations is not none:
# namespace package
sys.modules[spec.name] = module
else:
# unsupported
raise importerror
elif not hasattr(spec.loader, 'exec_module'):
module = spec.loader.load_module(spec.name)
# set __loader__ and __package__ if missing.
else:
sys.modules[spec.name] = module
try:
spec.loader.exec_module(module)
except baseexception:
try:
del sys.modules[spec.name]
except keyerror:
pass
raise
return sys.modules[spec.name]
'''#過程說明
''' 1、如果在 sys.modules 中存在指定名稱的模組物件,匯入操作會已經將其返回。
2、載入器執行模組**之前,該模組將存在於 sys.modules 中。 這一點很關鍵,因為該模組**可能(直接或間接地)匯入其自身;
預先將其新增到 sys.modules 可防止在最壞情況下的無限遞迴和最好情況下的多次載入。
3、如果載入失敗,則該模組 -- 只限載入失敗的模組 -- 將從 sys.modules 中移除。 任何已存在於 sys.modules 快取的模組,
4、在模組建立完成但還未執行之前,匯入機制會設定匯入相關模組屬性(在上面的示例偽**中為 「_init_module_attrs」),詳情參見 後續部分。
5、模組執行是載入的關鍵時刻,在此期間將填充模組的命名空間(也就是module.__dict__)。 執行會完全委託給載入器,由載入器決定要填充的內容和方式。
6、在載入過程中建立並傳遞給 exec_module() 的模組並不一定就是在匯入結束時返回的模組 [2]。
'''
python 模組載入
本文主要介紹python模組載入的過程。所有的module都是由物件和物件之間的關係組成。python中所有的東西都是物件,分為三類 型別type 類class和例項instance。三種物件之間的兩種關係 類和物件的關係可以通過內建方法type來辨別。python中,任何乙個類都是直接或間接繼承自...
python載入模組 Python 模組的載入順序
基本概念 module 模組,乙個 py 檔案或以其他檔案形式存在的可被匯入的就是乙個模組 package 包,包含有 init 檔案的資料夾 relative path 相對路徑,相對於某個目錄的路徑 absolute path 絕對路徑,全路徑 python 直譯器是如何查詢包和模組的 pyth...
python 模組的載入
不管是用import還是用from mmmm import 的方式匯入模組,當程式執行之後,回頭在看那個儲存著mmmm.py檔案的目錄中,多了乙個檔案 ls mmm mmmm.py mmmm.pyc 在這個目錄下面,除了原來的那個mmmm.py之外,又多了乙個mmmm.pyc檔案,這個檔案不是我寫的...