1. 程式人生 > >python--5、模塊

python--5、模塊

情況 -s 提高 number 腳本執行 app 因此 data 作用

模塊

程序的代碼根據作用分散寫入多個文件,這些文件相互引用,以實現程序的功能,這些文件即稱之為”模塊“。
自己定義的函數或者變量為了防止在解釋器中執行完退出後丟失,需要把代碼寫到文件中,再直接執行,稱為“腳本”。
但是程序在功能越來越多後,為了便於管理代碼,通常將一個程序分為多個文件,這樣使得程序結構更加清晰,也方便管理。這樣就可以吧他們當做模塊來導入到其他的模塊中。實現了功能復用。
同理,我們也可以拿來別人寫好的模塊來導入到自己的項目中使用,以提升開發效率。

一個模塊即包含Python定義和聲明的文件,模塊一般用於導入使用。

import 可以加載的模塊有:

  • Python編寫的.py文件
  • 已被變異為共享庫或DLL的C或C++擴展
  • 吧一系列模塊組織到一起的文件夾(包的概念在之後介紹)
  • 使用C編寫並鏈接到Python解釋器的內置模塊。

示例:

#test.py
print(‘this is test‘)
number = 123
def ins1():
    print(‘test模塊‘,number)
def ins2():
    print(‘test模塊‘)
    ins1()
def ins3():
    global number
    number = 0

import

模塊可以包含可執行的語句和函數的定義,為了初始化模塊。他們在模塊第一次被import導入時執行(即使在同一模塊在一個程序中import了很多次,只有第一次導入時將模塊加載到內存,後續的import只會引用)

註:我們可以從sys.module中找到當前已經加載的模塊,sys.module是一個字典,內部包含模塊名與模塊對象的映射,該字典決定了導入模塊時是否需要重新導入。

import導入過程

為相應模塊創建新的名稱空間, 在新創建的命名空間中執行模塊中包含的代碼,創建模塊名來引用該名稱空間。

  • 在整個導入模塊時,被導入模塊有獨立的名稱空間

被導入的每個模塊都是一個獨立的名稱空間,定義在模塊中的函數把這個模塊當作全局名稱空間,可防止模塊的全局變量與調用它的文件的全局變量沖突。

  • 為模塊起別名
import test as tt
print(tt.money)

例如兩個相似的模塊有兩個的功能一樣的方法。根據用戶輸入判定該是哪個模塊,再給這個模塊起成特定的別名。\

  • 在一行導入多個模塊
import module1,module2,……

from module_name import func

與import的對比

  • from .. import ..,是將模塊中的方法名字直接導入到當前的名稱空間中,so,在當前文件名稱空間中,直接使用名字即可。
    若導入的模塊方法中還需回掉原來模塊的別的方法or變量,則還是以原模塊中的為準。
    若是導入的模塊方法直接與現文件中的方法沖突,則導入進來的會被覆蓋掉。
  • 也支持as,對導入的方法做別名。
  • 也支持","導入多個

from .. import *

把模塊中非"_"下劃線開頭的名字都導入到當前位置。
這個可以使用__all__來控制*導入的方法。
#__all__=[‘money‘,‘read1‘] #這樣在另外一個文件中用from spam import *就這能導入列表中規定的兩個名字

模塊的重載(不重要)

模塊被導入後,被放到sys.module的字典中。若改變了模塊內容,必須重啟程序。python不支持重新加載或卸載之前導入的模塊。
哪怕在sys.module中刪了模塊對象,但仍有可能被其他程序組件引用。不會清掉。
尤其是引用了這個模塊中的一個類,用這個類產生了很多對象,因而這些對象都有關於這個模塊的引用。

兩種python文件

  • 腳本:一個文件就是整個程序,用於被執行。
  • 模塊:文件中存放著一堆功能,用於被導入使用。

python內置的全局變量__name__

  • 當文件被當作腳本執行時:__name__ 等於 ‘__main__‘
  • 當文件被當作模塊導入時:__name__等於模塊名

用於控制.py文件在不同的應用場景下執行不同的邏輯。

模塊的搜索路徑

內存中已經加載的模塊 -> 內置模塊 -> sys.path路徑中包含的模塊。
#我們自定義的模塊名不應該與系統內置模塊重名。

可以通過修改sys.path來添加環境變量。

import sys
sys.path.append(‘/a/b/c‘)
sys.path.insert(0,‘/x/y/z‘)

搜索環境變量時會在sys.path中從左往右找,sys.path中還可以包含.zip文件和.egg文件,python會把.zip文件當作一個目錄取處理。

#.egg文件是由setuptools創建的包,這是按照第三方python庫和擴展時使用的一種常見格式,.egg文件實際上只是添加了額外元數據(如版本號,依賴項等)的.zip文件。

#要強調的:只能從.zip文件中導入.py,.pyc等文件。使用C編寫的共享庫和擴展塊無法直接從.zip文件中加載(此時setuptools等打包系統有時能提供一種規避方法),且從.zip中加載文件不會創建.pyc或者.pyo文件,因此一定要事先創建他們,來避免加載模塊是性能下降。

編譯Python文件

為了提高“加載模塊的速度”,Python解釋器會在__pycache__目錄中緩存每個模塊編譯後版本,格式:module.version.pyc。保證了編譯後的結果可多版本共存。
#python檢查源文件的修改時間與編譯的版本進行對比,如果過期就需要重新編譯,這是自動的過程。且編譯的模塊是平臺獨立的。所以相同的庫可以在不同架構的系統之間共享,即pyc是一種跨平臺的字節碼,類似於JAVA .net。是由python虛擬機來執行的,但是pyc的內容跟python的版本相關,不同的版本編譯後的pyc文件不同,2.5編譯的Pyc文件不能到3.5上執行,並且pyc文件是可以反編譯的。因而它的出現僅僅是用來提升模板的加載速度的,而不是用來加密

python解釋器在以下兩種情況下不檢測緩存

#1 如果是在命令行中被直接導入模塊,則按照這種方式,每次導入都會重新編譯,並且不會存儲編譯後的結果(python3.3以前的版本應該是這樣)
python -m spam.py

#2 如果源文件不存在,那麽緩存的結果也不會被使用,如果想在沒有源文件的情況下來使用編譯後的結果,則編譯後的結果必須在源目錄下
#註:

    • 模塊名區分大小寫,foo.py與FOO.py代表的是兩個模塊
    • 只有使用import語句是才將文件自動編譯為.pyc文件,在命令行或標準輸入中指定運行腳本則不會生成這類文件,因而我們可以使用compieall模塊為一個目錄中的所有模塊創建.pyc文件

python--5、模塊