模塊和包
一.模塊
1.什麽是模塊
一個模塊就是包含了python 定義和聲明的文件,文件名就是模塊名加.py後綴
2.模塊的作用
方便管理,使功能得到重復利用
3.使用模塊
3.1 模塊可以包含可執行的語句和函數的定義,這些語句的目的是初始化模塊,它們只在模塊名第一次遇到導入import語句時才執行,第一次導入後就已將模塊名加載到內存中了。
3.2 每個模塊都是一個獨立的名稱空間,定義在這個模塊中的函數,把這個模塊的名稱空間當作全局名稱空間,編寫自己的模塊時不用擔心與使用者的全局變量發生沖突。
3.3 首次導入模塊my_moudle時會做三件事:
2.在新創建的命名空間中執行模塊中包含的代碼,見初始導入import my_moudle
3.創建名字my_moudle來引用該命名空間
3.4 為模塊起名
#import my_module as sm #print(sm.money)
3.5 在一行中導入多個模塊
#import sys,os,re
3.6 from...import
#from my_module import read1,read2 #這樣可以直接用模塊中的名字 #如果當前文件中有和module中一樣的名字比如都有read(),則會被覆蓋
註意:python中的變量賦值不是一種存儲操作,而只是一種綁定關系
#from my_moudle import money,read1 #money=100 #將當前位置的名字money綁定到了100 #print(money) #打印當前的名字 #read1() #讀取my_moudle.py中的名字money,仍然為1000 ‘‘‘ #from the my_moudle.py #my_moudle->read1->money 1000 ‘‘‘
3.7 支持as,也支持多行導入
#from my_moudle import read1 as read # from my_moudle import (read1, # read2, # money)
3.8 from my_moudle import * 把my_moudle中所有的不是以下劃線(_)開頭的名字都導入到當前位置,大部分情況下我們的python程序不應該使用這種導入方式,因為*你不知道你導入什麽名字,很有可能會覆蓋掉你之前已經定義的名字。而且可讀性極其的差,在交互式環境中導入時沒有問題。
#from my_moudle import * #將模塊my_moudle中所有的名字都導入到當前名稱空間 #print(money) #print(read1) #print(read2) #print(change) #執行結果: #from the my_moudle.py #<function read1 at 0x1012e8158> #<function read2 at 0x1012e81e0> #<function change at 0x1012e8268>
#在my_moudle.py中新增一行 #__all__=[‘money‘,‘read1‘] #這樣在另外一個文件中用from my_moudle import *就這能導入列表中規定的兩個名字
3.9考慮到性能的原因,每個模塊只被導入一次,放入字典sys.module中,如果你改變了模塊的內容,你必須重啟程序,python不支持重新加載或卸載之前導入的模塊
#def func1(): # print(‘func1‘) #import time,importlib #import aa #time.sleep(20) # importlib.reload(aa) #ctrl + s 可以更改 #aa.func1()
4.0把模塊當作腳本執行
我們可以通過模塊的全局變量__name__來查看模塊名:
當做腳本運行:
__name__ 等於‘__main__‘
當做模塊導入:
__name__= 模塊名
作用:用來控制.py文件在不同的應用場景下執行不同的邏輯
if __name__ == ‘__main__‘:
def fib(n): a, b = 0, 1 while b < n: print(b, end=‘ ‘) a, b = b, a+b print() if __name__ == "__main__": print(__name__) num = input(‘num :‘) fib(int(num))
4.1 模塊搜索路徑
內存中已經加載的模塊->內置模塊->sys.path路徑中包含的模塊
4.2 編譯python文件
為了提高模塊的的加載速度,python解釋器會在__pycache__目錄中下緩存每個模塊編譯後的版本,格式為:module.version.pyc。通常會包含python的版本號。例如,在CPython3.3版本下,my_moudle.py模塊會被緩存成__pycache__/my_moudle.cpython-33.pyc。這種命名規範保證了編譯後的結果多版本共存。
二.包
2.1
1. 無論是import形式還是from...import形式,凡是在導入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關於包才有的導入語法
2. 包是目錄級的(文件夾級),文件夾是用來組成py文件(包的本質就是一個包含__init__.py文件的目錄)
3. import導入文件時,產生名稱空間中的名字來源於文件,import 包,產生的名稱空間的名字同樣來源於文件,即包下的__init__.py,導入包本質就是在導入該文件
強調:
1. 在python3中,即使包下沒有__init__.py文件,import 包仍然不會報錯,而在python2中,包下一定要有該文件,否則import 包報錯
2. 創建包的目的不是為了運行,而是被導入使用,記住,包只是模塊的一種形式而已,包即模塊
2.2
註意:
1.關於包相關的導入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什麽位置,在導入時都必須遵循一個原則:凡是在導入時帶點的,點的左邊都必須是一個包,否則非法。可以帶有一連串的點,如item.subitem.subsubitem,但都必須遵循這個原則。
2.對於導入後,在使用時就沒有這種限制了,點的左邊可以是包,模塊,函數,類(它們都可以用點的方式調用自己的屬性)。
3.對比import item 和from item import name的應用場景:
如果我們想直接使用name那必須使用後者。
2.3 from ..import ...
需要註意的是from後import導入的模塊,必須是明確的一個不能帶點,否則會有語法錯誤,如:from a import b.c是錯誤語法
2.4 __init__.py文件
不管是哪種方式,只要是第一次導入包或者是包的任何其他部分,都會依次執行包下的__init__.py文件(我們可以在每個包的文件內都打印一行內容來驗證一下),這個文件可以為空,但是也可以存放一些初始化包的代碼。
模塊和包