模塊
導入模塊
Python官方教程讓我們在Python解釋器中練習。但是當我們結束解釋器,所有的代碼都消失了。如果我們希望讓代碼永久保存的話,就需要將它們保存到文件中。每一個以.py
結尾的文件,都是一個Python模塊。我們可以在代碼中使用import
關鍵字導入其他模塊。
print('--------------導入模塊--------------')
import sys
print(f'{sys.path}')
導入模塊之后,我們就可以使用該模塊中的所有函數了,就像上面那樣。不過這種方式,每次都需要添加模塊名和點號。有沒有什么方法可以向Java的靜態導入那樣,直接使用函數而不需要模塊名呢?當然也是可行的,不過這需要下面的導入方式。
from io import *
這種方式雖然簡單,但是要注意適當使用。因為有些函數可能出現重名。所以最好的辦法還是使用第一種,當然如果你的代碼很小,確認沒重名,那么使用哪種方法都可以。
執行模塊
有時候我們不僅需要導入一個模塊的函數,還需要執行一個模塊中的代碼。執行代碼可以使用下面的命令。
python 文件名.py <參數>
默認情況下,當我們導入一個模塊的時候,它的代碼就會自動執行。如果我們需要將導入和執行分隔開,不想在導入的時候執行模塊,就需要在模塊中添加類似下面的代碼。
if __name__ == "__main__":
# ....
這里用到了另一個內置變量__name__
。當前執行的文件的__name__
的值是__main__
,導入的文件的__name__
是模塊的名稱。所以我們可以使用該變量來判斷模塊是被導入的,還是被執行的。
模塊的查找
模塊的查找路徑如下:
- 包含當前輸入文件的文件夾(如果沒有就是解釋器的當前文件夾)。
-
PYTHONPATH
變量(和系統環境變量PATH語法相同)、 - Python安裝文件夾。
具體說來我們可以使用sys
模塊的path()
方法獲取模塊文件夾。
import sys
print(f'{sys.path}')
在我電腦上輸出如下。
['D:\\Desktop\\python-study\\python-samples', 'D:\\Desktop\\python-study\\python-samples', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36', 'C:\\Python36\\lib\\site-packages']
dir內置函數
我們都知道在windows命令提示符下輸入dir
就會列出當前文件夾信息,類似Linux中的ls
。在Python中也有一個內置函數dir()
,它會返回給定模塊下定義的所有名稱。如果沒指定參數,那么dir()
函數會返回當前模塊下的所有名稱。
包
定義包
包是一種組織模塊的方式。相信你在Java或者其他語言中也已經了解過包的作用了。Python官方教程為我們列舉了一個典型的包結構。可以看到,包和一般的文件夾沒什么區別,關鍵是包文件夾下必須包含一個__init__.py
,表明這是一個包。
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
導入包
定義了包之后,我們就可以導入包了。語法和導入模塊類似,不過這次我們需要制定完整包名了。
import sound.effects.echo
當然導入之后使用的時候也需要制定完整包名。
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
如果嫌麻煩也可以將包內容直接導入到當前名字空間下。這樣以后使用的時候就不需要寫整個包名了。
from sound.effects import echo
在Python中導入包、子包、模塊的語法完全相同。所以我們可以僅把最末尾的子包直接導入到當前名字空間下,這樣一方面節省了書寫成本,名字沖突的風險也不會太大。
包導入控制
如果我們使用from sound.effects import *
將所有模塊都導入,會發生什么事情呢?這樣會將該包下的所有子包的所有模塊都導入。如果包比較大的話就會出現性能問題。所以一般我們都需要對一次性導入的模塊進行控制。
方法也很簡單,在包的__init__.py
文件中,操作__all__
變量。在__all__
變量中,指定要導入的包。這樣以后就算使用通配符一次性導入所有模塊,也只會導入這里定義的模塊。
__all__ = ["echo", "surround", "reverse"]