這篇文章将會介紹 Python 中子產品與包的相關内容
1、子產品與包
子產品 (
module
) 這個概念最初是為了代碼封裝和可重用性而出現的,每個字尾為
.py
的檔案都是一個子產品
而包 (
package
) 是為了更好地組織子產品而發展出來的概念,在 Python 3.3 後,每個目錄都被稱為一個包
而在 Python 3.3 之前,隻有目錄中有
__init__.py
才會被識别為一個包
2、導入子產品
我們可以使用
import
語句導入子產品,正常的文法是
import module
, 在首次導入子產品時:
- 首先建立一個新的命名空間,并在該命名空間内執行子產品
中的代碼module
- 然後在目前命名空間用名稱
引用新的命名空間module
是以我們在目前命名空間内才能通過
module.symbol
通路子產品中的變量
>>> import random
>>> random.randint(0, 1)
# 1
我們也能使用
from module import symbol
從
module
中導入指定的
symbol
到目前命名空間
這樣我們就能在目前命名空間直接通路導入的變量,但是要注意此時不能通路子產品中的其他變量
>>> from random import randint
>>> randint(0, 1)
# 1
我們還能通過
as
用指定的名稱引用新的命名空間和導入的變量
>>> # 通過 `as` 指定名稱引用新的命名空間
>>> import random as rd
>>> rd.randint(0, 1)
# 1
>>> # 通過 `as` 指定名稱引用導入的變量
>>> from random import randint as ri
>>> ri(0, 1)
# 1
3、導入包
我們可以用
import
語句導入包,正常的文法是
import package
,在執行這條語句時:
- 首先建立一個新的命名空間,并在該命名空間内執行包内
中的代碼__init__.py
- 然後在目前命名空間用名稱
引用新的命名空間package
__init__.py
一般用于指定導出的内容,若該檔案缺失或内容為空,
import package
不會有任何效果
import package
print(package.module.symbol)
我們也能用
from package import module
從
package
中導入指定的
module
到目前命名空間
這樣我們就能在目前命名空間直接通路導入的子產品
module
以及子產品中的變量
from package import module
print(module.symbol)
我們還能用
from package.module import symbol
從
package
中的
module
導入指定的
symbol
這樣我們就能在目前命名空間直接通路導入的變量
symbol
from package.module import symbol
print(symbol)
4、搜尋路徑
下面讓我們思考一個更深入的問題?當我們使用
import
語句導入子產品時,解釋器在哪裡找所需的子產品呢?
- 緩存路徑(可以通過
檢視,儲存着之前導入的所有子產品及其查找路徑)sys.modules
- 内置子產品(可以通過
檢視)sys.builtin_module_names
- 其他位置(可以通過
檢視,包括入口檔案所在目錄、sys.path
環境變量指定目錄)PYTHONPATH
如果現在我們需要讓程式引用一個不在上述路徑所指定的目錄中的子產品,可以怎麼處理呢?
一個簡單而有效的辦法就是在程式中修改
sys.path
的值,添加上述子產品所在路徑即可
5、隐藏測試代碼
在編寫子產品時,我們常常需要對子產品進行單元測試,等待測試成功後才會将其應用到其它程式上
由于測試所需,在子產品中可能會留下大量測試代碼,這些測試代碼在子產品被引用時可能會影響到正常運作
是以,我們有必要在子產品中隐藏測試代碼,具體的方法如下:
在 Python 中有一個内置變量
__name__
,隻有當一個檔案作為入口檔案時,它的值才為
__main__
是以我們可以将測試代碼寫在以下條件語句塊内,這樣的話隻有在直接運作子產品時才會執行這些代碼
if __name__ == '__main__':
# 測試代碼
6、子產品查詢
最後一個問題,當我們看到一個從未接觸過的子產品時,可以在哪裡進行學習呢?通常有以下幾種途徑:
-
:列出子產品的簡短說明mudule.__doc__
>>> import random
>>> print(random.__doc__)
# Random variable generators.
#
# integers
# --------
# uniform within range
#
# sequences
# ---------
# pick random element
# pick random sample
# pick weighted random sample
# generate random permutation
#
# distributions on the real line:
# ------------------------------
# uniform
# triangular
# normal (Gaussian)
# lognormal
# negative exponential
# gamma
# beta
# pareto
# Weibull
#
# distributions on the circle (angles 0 to 2pi)
# ---------------------------------------------
# circular uniform
# von Mises
#
# General notes on the underlying Mersenne Twister core generator:
#
# * The period is 2**19937-1.
# * It is one of the most extensively tested generators in existence.
# * The random() method is implemented in C, executes in a single Python step,
# and is, therefore, threadsafe.
-
:列出子產品的可用接口module.__all__
>>> import random
>>> print(random.__all__)
# ['Random', 'seed', 'random', 'uniform', 'randint', 'choice', 'sample', 'randrange', 'shuffle', 'normalvariate', 'lognormvariate', 'expovariate', 'vonmisesvariate', 'gammavariate', 'triangular', 'gauss', 'betavariate', 'paretovariate', 'weibullvariate', 'getstate', 'setstate', 'getrandbits', 'choices', 'SystemRandom']
-
:列印子產品源代碼的所在路徑module.__file__
>>> import random
>>> print(random.__file__)
# C:\Python\Python37-32\lib\random.py
-
:檢視幫助手冊,擷取更多資訊help(module)
- 最後一個方法當然是直接看官方文檔的說明啦:https://docs.python.org