python基础---模块与包
1、模塊導(dǎo)入方法
常見(jiàn)的場(chǎng)景:
一個(gè)模塊就是一個(gè)包含了python定義和聲明的文件,文件名就是模塊名字加上.py的后綴,導(dǎo)入模塊可以實(shí)現(xiàn)功能的重復(fù)利用
import加載的模塊分為四個(gè)通用類別:
1?使用python編寫(xiě)的代碼(.py文件)
2?已被編譯為共享庫(kù)或DLL的C或C++擴(kuò)展
3?包好一組模塊的包
4?使用C編寫(xiě)并鏈接到python解釋器的內(nèi)置模塊
?
a. import語(yǔ)句
python?內(nèi)置了很多模塊,比如os、sys、time等,也可以是自定義模塊、模塊包、C擴(kuò)展等,使用import無(wú)法區(qū)分導(dǎo)入的模塊類型
import?模塊名??????
例如:導(dǎo)入spam.py
import?spam(不含.py)
導(dǎo)入多個(gè)模塊:
import os,time,sys
?
模塊可以包含可執(zhí)行的語(yǔ)句和函數(shù)的定義,這些語(yǔ)句的目的是初始化模塊,它們只在模塊名第一次遇到導(dǎo)入import語(yǔ)句時(shí)才執(zhí)行(import語(yǔ)句是可以在程序中的任意位置使用的,且針對(duì)同一個(gè)模塊import很多次,為了防止你重復(fù)導(dǎo)入,python的優(yōu)化手段是:第一次導(dǎo)入后就將模塊名加載到內(nèi)存了,后續(xù)的import語(yǔ)句僅是對(duì)已經(jīng)加載大內(nèi)存中的模塊對(duì)象增加了一次引用,不會(huì)重新執(zhí)行模塊內(nèi)的語(yǔ)句)
?
每個(gè)模塊都是一個(gè)獨(dú)立的名稱空間,定義在這個(gè)模塊中的函數(shù),把這個(gè)模塊的名稱空間當(dāng)做全局名稱空間,這樣我們?cè)诰帉?xiě)自己的模塊時(shí),就不用擔(dān)心我們定義在自己模塊中全局變量會(huì)在被導(dǎo)入時(shí),與使用者的全局變量沖突
?
導(dǎo)入模塊干了哪些事:
1?執(zhí)行源文件
2?以一個(gè)源文件的全局名稱空間
3?在當(dāng)前位置拿到一個(gè)模塊名,指向2創(chuàng)建的名稱空間
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #測(cè)試一:money與spam.money不沖突 #test.py import?spam money=10 print(spam.money) 輸出: from?the?spam.py 1000 ?? #測(cè)試二:read1與spam.read1不沖突 #test.py import?spam def?read1(): ?????print('========') spam.read1() 輸出: from?the?spam.py spam->read1->money1000 #測(cè)試三:執(zhí)行spam.change()操作的全局變量money仍然是spam中的 #test.py import?spam money=1 spam.change() print(money) 輸出: from?the?spam.py 1 |
?
模塊別名功能
練習(xí):
有兩鐘sql模塊mysql和oracle,根據(jù)用戶的輸入,選擇不同的sql功能
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #mysql.py def?sqlparse(): ????print('from?mysql?sqlparse') ?? #oracle.py def?sqlparse(): ????print('from?oracle?sqlparse') ?? #test.py db_type=input('>>:?') if?db_type?==?'mysql': ????import?mysql?as?db elif?db_type?==?'oracle': ????import?oracle?as?db ?? db.sqlparse() |
?
????????為已經(jīng)導(dǎo)入的模塊起別名的方式對(duì)編寫(xiě)可擴(kuò)展的代碼很有用,假設(shè)有兩個(gè)模塊xmlreader.py和csvreader.py,它們都定義了函數(shù)read_data(filename):用來(lái)從文件中讀取一些數(shù)據(jù),但采用不同的輸入格式。可以編寫(xiě)代碼來(lái)選擇性地挑選讀取模塊
| 1 2 3 4 5 | if?file_format?==?'xml': ????import?xmlreader?asreader elif?file_format?==?'csv': ????import?csvreader?asreader data=reader.read_date(filename) |
?
b. from…import語(yǔ)句
from?模塊名? import?模塊名中的方法
例如:from spamimport money,read1,read2,change
?
如果模塊中的方法太多,可以使用:
from spam import? *?????(不推薦使用,容易與執(zhí)行文件的命名空間沖突)
__all__=['money','x'] ? ? ?#對(duì)from spam import *?有用,之后導(dǎo)入money、x方法
_money=1000 ? ? ? ? ? ? #對(duì)from spam import *?有用,不會(huì)導(dǎo)入這個(gè)方法
?
對(duì)比import spam,會(huì)將源文件的名稱空間'spam'帶到當(dāng)前名稱空間中,使用時(shí)必須是spam.名字的方式,而from?語(yǔ)句相當(dāng)于import,也會(huì)創(chuàng)建新的名稱空間,但是將spam中的名字直接導(dǎo)入到當(dāng)前的名稱空間中,在當(dāng)前名稱空間中,直接使用名字就可以了
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #spam.py print('from?the?spam.py') money=0 def?read1(): ????print('spam->read1->money',money) def?read2(): ????print('spam->read2?calling?read') ????read1() def?change(): ????global?money ????money=0? ?? #?執(zhí)行文件 from?spam?import?money,read1,read2,change money=0 print(money) print(read1) 輸出: from?the?spam.py????????????????????#首先執(zhí)行spam.py 0??????????????????????#仍然是當(dāng)前執(zhí)行文件的命名空間中的money <function?read1?at?0x00000000026DE950> |
優(yōu)點(diǎn):使用源文件內(nèi)的名字時(shí)無(wú)需加前綴,使用方便
缺點(diǎn):容易與當(dāng)前文件的名稱空間內(nèi)的名字混淆
?
c.?模塊搜索路徑
模塊只在第一次導(dǎo)入時(shí)才會(huì)執(zhí)行,之后的導(dǎo)入都是直接引用內(nèi)存已經(jīng)存在的結(jié)果
import sys
print('spam' in sys.modules) ?????????? #存放的是已經(jīng)加載到內(nèi)的模塊
注意:自定義的模塊名一定不要與python自帶的模塊名重名
模塊的查找順序是:內(nèi)存中已經(jīng)加載的模塊->內(nèi)置模塊->sys.path路徑中包含的模塊
| 1 2 3 4 5 6 7 8 9 | import?time import?importlib import?spam???????????#導(dǎo)入模塊會(huì)把硬盤(pán)中的模塊內(nèi)容加載到內(nèi)存中 time.sleep(20) import?spam???????????#再次導(dǎo)入會(huì)直接從內(nèi)存中查找,忽略硬盤(pán)中模塊內(nèi)容 print(spam.money) importlib.reload(spam)?????????#會(huì)重新加載模塊(只在測(cè)試環(huán)境使用) print(spam.money) |
?
import sys
print(sys.path)????????????? #模塊的搜索路徑
sys.path從以下位置初始化
??? 1 ?執(zhí)行文件所在的當(dāng)前目錄
??? 2 ?PTYHONPATH(包含一系列目錄名,與shell變量PATH語(yǔ)法一樣)
??? 3 ?依賴安裝時(shí)默認(rèn)指定的
加入模塊路徑:
| 1 2 3 4 | import?sys print(sys.path) sys.path.insert(0,r'要添加的模塊路徑')???????#插入模塊路徑 sys.path.append(r'要添加的模塊路徑')?????????#追加模塊路徑 |
?
d.?區(qū)分python文件的兩種用途
文件當(dāng)做腳本(執(zhí)行文件)運(yùn)行時(shí)__name__等于__main__
文件當(dāng)做模塊被加載運(yùn)行時(shí)__name__等于模塊名
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #?m1.py import?os,sys x=1 def?func1(): ????print('from?m1') def?func2(): ????print('from?m2') def?func3(): ????print('from?m3') #?print(__name__) #文件當(dāng)做腳本運(yùn)行時(shí)__name__等于__main__ #文件當(dāng)做模塊被加載運(yùn)行時(shí)__name__等于模塊名 if?__name__?==?'__main__': ????#當(dāng)做腳本使用時(shí)才執(zhí)行 ????func1() ????func2() ????func3()? #?run.py ?? import?m1????????????#導(dǎo)入m1模塊 m1.func3() |
?
e.?包
python3中創(chuàng)建文件夾會(huì)自動(dòng)創(chuàng)建__init__.py
python2中創(chuàng)建包需要手動(dòng)創(chuàng)建__init__.py
1.?無(wú)論是import形式還是from...import形式,凡是在導(dǎo)入語(yǔ)句中(而不是在使用時(shí))遇到帶點(diǎn)的,都要第一時(shí)間提高警覺(jué):這是關(guān)于包才有的導(dǎo)入語(yǔ)法
2.?包是目錄級(jí)的(文件夾級(jí)),文件夾是用來(lái)組成py文件(包的本質(zhì)就是一個(gè)包含__init__.py文件的目錄)
3. import導(dǎo)入文件時(shí),產(chǎn)生名稱空間中的名字來(lái)源于文件,import?包,產(chǎn)生的名稱空間的名字同樣來(lái)源于文件,即包下的__init__.py,導(dǎo)入包本質(zhì)就是在導(dǎo)入該文件
強(qiáng)調(diào):
?1.?在python3中,即使包下沒(méi)有__init__.py文件,import?包仍然不會(huì)報(bào)錯(cuò),而在python2中,包下一定要有該文件,否則import?包報(bào)錯(cuò)
?2.?創(chuàng)建包的目的不是為了運(yùn)行,而是被導(dǎo)入使用,記住,包只是模塊的一種形式而已,包即模塊
? ??3.凡是在導(dǎo)入時(shí)帶點(diǎn)的,點(diǎn)的左邊都必須是一個(gè)包
本文轉(zhuǎn)自lyndon博客51CTO博客,原文鏈接http://blog.51cto.com/lyndon/1953171如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
遲到的棟子
總結(jié)
以上是生活随笔為你收集整理的python基础---模块与包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 配置 LBaaS - 每天5分钟玩转 O
- 下一篇: 从容稳进,高通正扎实推进5G