什麼是包?python
隨着模塊數目的增多,把全部模塊不加區分地放到一塊兒也是極不合理的,因而Python爲咱們提供了一種把模塊組函數
織到一塊兒的方法,即建立一個包。包就是一個含有__init__.py
文件的文件夾,文件夾內能夠組織子模塊或子設計
包,例如code
pool/ #頂級包 ├── __init__.py ├── futures #子包 │ ├── __init__.py │ ├── process.py │ └── thread.py └── versions.py #子模塊
[一句話]it
包就是一個包含有__init__.py
文件的文件夾,本質是模塊的一種形式,是用來被當作模塊導入io
[強調]模板
py2下想要導入包,包下面必需要有__init__.py文件,不然導入報錯 py3下的包沒有__init__.py文件,導入包也不會報錯,可是你沒法取到名字
爲何使用包class
當你做爲模塊的設計者,模塊的功能越寫越多的時候,用包可以分文件的更好的管理,拓展本身的功能thread
可是在使用者層面上不更改使用方法import
__init__.py
[導入包發生的三件事]
import mmm
產生一個名稱空間
運行包下的__init__.py
文件,將運行過程當中產生的名字都丟到1的名稱空間中
在當前執行文件的名稱空間中拿到一個名字mmm,mmm指向1的名稱空間mmm中的名字通通來自
__init__.py
的名稱空間,或者通俗的說,mmm指向的就是__init__.py
的名稱空間
也就是說導入包時並不會導入包下全部的子模塊與子包
[強調]
1.關於包相關的導入語句也分爲import和from ... import ...兩種,可是不管哪一種,不管在什麼位置,在導入時都必須遵循一個原則:凡是在導入時帶點的,點的左邊都必須是一個包,不然非法。能夠帶有一連串的點,如import 頂級包.子包.子模塊,但都必須遵循這個原則。但對於導入後,在使用時就沒有這種限制了,點的左邊能夠是包,模塊,函數,類(它們均可以用點的方式調用本身的屬性)。 二、包A和包B下有同名模塊也不會衝突,如A.a與B.a來自倆個命名空間 三、import導入文件時,產生名稱空間中的名字來源於文件,import 包,產生的名稱空間的名字一樣來源於文件,即包下的__init__.py,導入包本質就是在導入該文件
針對包內的模塊之間的導入有兩種方式
[絕對導入]
# 以頂級包爲起始 # mmm下的__init__.py from mmm.m1 import f1
[相對導入]
# .表明當前文件所在的目錄,..表明當前目錄的上一級目錄,依此類推 # 僅限於包內使用,不能跨出包(包內模塊之間的導入,推薦使用相對導入) # mmm下的__init__.py from ..m1 import f1
import也能使用絕對導入,導入過程當中一樣會依次執行包下的__init__.py,只是基於import導入的結果,使用時必須加上該前綴
[強調]
1. 相對導入不能跨出包,因此相對導入僅限於包內模板彼此之間鬧着玩 2. 而絕對導入是沒有任何限制的.因此絕對導入是一種通用的導入方式
[總結]
不管是哪一種導入方式,若是你想要使用者可以使用你包裏面全部文件(模塊)的功能,那就必須在包下面的
__init__.py
文件導入全部文件(模塊)裏面的名字
在使用包時一樣支持from mmm.m1 import *
,毫無疑問表明的是futures下__init__.py
中全部的名
字,通用是用變量__all__
來控制*
表明的意思
#mmm下的__init__.py __all__ = ['f1',]
導包中的sys.path
在包的導入中和模塊同樣,查找名字的順序也是從sys.path
這個列表中找,可是注意是運行文件的sys.path
不是包裏面的__init__.py
的sys.path