1. 程式人生 > >模塊(一)

模塊(一)

lap 創建 支持 目的 file 順序查找 版本 就是 其他

什麽是模塊

模塊就是一系列功能的集合體,在python當中,一個py文件就是一個模塊,例如:spam.py 就是一個模塊,其中spam就是模塊名,可以通過“import spam”來調用

模塊主要分為三個部分:

1、內置模塊,例如 “time”,“os”等python解釋器當中內置

2、自己用python編寫的py文件

3、下載別人已經編寫好的模塊導入自己文件當中(這種拿來主義可以大大提高我們的開發效率)

在我們最開始學習python開始只是使用簡單的數據類型和一些流程控制就可以開始編寫一些簡單的程序,但是這種編寫方式在代碼量大的情況下就很不方便,後來我們又學習了函數可以將重復的功能定義成函數,通過函數名就可以來重復的調用,但是我們不可能將所有的功能全部都放到一個文件當中,這就需要用到模塊,將一些功能分別編寫到不同的文件當中,通過import調用,這樣從文件級別來組織程序會讓程序的條理更加清晰,更加方便管理,也能實現功能的重復利用

import的使用

#模塊可以包含可執行的語句和函數的定義,這些語句的目的是初始化模塊,它們只在模塊名第一次遇到導入import語句時才執行(import語句是可以在程序中的任意位置使用的,且針對同一個模塊很import多次,為了防止你重復導入,python的優化手段是:第一次導入後就將模塊名加載到內存了,後續的import語句僅是對已經加載到內存中的模塊對象增加了一次引用,不會重新執行模塊內的語句)

#test.py
import spam #只在第一次導入時才執行spam.py內代碼,此處的顯式效果是只打印一次‘from the spam.py‘,當然其他的頂級代碼也都被執行了,只不過沒有顯示效果.
import spam import spam import spam ‘‘‘ 執行結果: from the spam.py ‘‘‘

import首次導入模塊的三道程序:

1、創建一個模塊的名稱空間

這個名稱空間屬於全局名稱空間一級別的

2、執行模塊對應的文件,將產生的名字存放於 “ l ” 的名稱空間

3、在當前執行的文件中拿到一個文件名,以該文件名來引用該名稱空間

這個名字和變量名沒什麽區別,與全局變量屬於一個級別,且使用spam.名字的方式

可以訪問spam.py文件中定義的名字,spam.名字與test.py中的名字來自

兩個完全不同的地方

因為import導入摸塊所創建的名稱空間屬於全局名稱空間一級別的,所以我們在導入模塊中的名字時不必擔心會被執行文件當中的名字沖突掉

為模塊起別名

為已經導入的模塊起別名的方式對編寫可擴展的代碼很有用

1 import spam as sm
2 print(sm.money)

有兩中sql模塊mysql和oracle,根據用戶的輸入,選擇不同的sql功能

# mysql.py
def parse():
    print(hello world)
#  oracle.py
def parse():
    print(HELLO WORLD)

# 執行文件
# inp=input(‘>>:‘).strip()
# if inp==‘mysql‘:
#     import mysql as db
# elif inp==‘oracle‘:
#     import oracle as db
# db.parse()

import導入模塊還可以一行導入多個模塊

 import sys,os,re   #(這種方式不建議多用)

from...import

在使用from...import時執行時與import執行前兩件事一樣

第三步是:在當前名稱空間中直接拿到模塊中的名字,可以直接使用,不用任何前綴

# from mysql import parse
# parse()

優點:使用比import更加方便

缺點:容易與當前執行文件當中的名字產生沖突

在from...import當中與import當中一樣支持用 “ as ” 來為模塊起別名,一行導入多個模塊

當一個模塊當中有多樣功能的時候,我們可以使用 “ from... import * ”來將模塊當中所有不是以下劃線開頭的全部導入當前位置

但是這種當時的可讀性非常差,我們沒有辦法分清我們導入了哪些名字

這種時候我們可以使用 “ __all__ ” 來控制 “ * ” 的範圍

#  在模塊中新增一行
__all__=[money,read1] #這樣在另外一個文件中用from spam import *就這能導入列表中規定的兩個名字

模塊的查找順序

1、內存中已經加載的模塊

2、內置模塊

3、sys.path路徑中包含的模塊

sys.path的第一個路徑是當前執行的文件夾

技術分享圖片
#模塊的查找順序
1、在第一次導入某個模塊時(比如spam),會先檢查該模塊是否已經被加載到內存中(當前執行文件的名稱空間對應的內存),如果有則直接引用
    ps:python解釋器在啟動時會自動加載一些模塊到內存中,可以使用sys.modules查看
2、如果沒有,解釋器則會查找同名的內建模塊
3、如果還沒有找到就從sys.path給出的目錄列表中依次尋找spam.py文件。


#sys.path的初始化的值來自於:
The directory containing the input script (or the current directory when no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
The installation-dependent default.

#需要特別註意的是:我們自定義的模塊名不應該與系統內置模塊重名。雖然每次都說,但是仍然會有人不停的犯錯。 

#在初始化後,python程序可以修改sys.path,路徑放到前面的優先於標準庫被加載。
1 >>> import sys
2 >>> sys.path.append(/a/b/c/d)
3 >>> sys.path.insert(0,/x/y/z) #排在前的目錄,優先被搜索
註意:搜索時按照sys.path中從左到右的順序查找,位於前的優先被查找,sys.path中還可能包含.zip歸檔文件和.egg文件,python會把.zip歸檔文件當成一個目錄去處理,

#首先制作歸檔文件:zip module.zip foo.py bar.py 
import sys
sys.path.append(module.zip)
import foo,bar

#也可以使用zip中目錄結構的具體位置
sys.path.append(module.zip/lib/python)


#windows下的路徑不加r開頭,會語法錯誤
sys.path.insert(0,rC:\Users\Administrator\PycharmProjects\a)
 

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

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

模塊(一)