Python基础(七)--模块和包
?
目錄
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Python基礎(七)--模塊和包
1 模塊
1.1 什么是模塊
1.2 模塊的使用
1.3 模塊的搜索路徑
1.4 模塊的緩存
2 包
2.1 什么是包
2.2 包的使用
3 常用模塊
3.1 math
3.2 random
3.3 time
3.4 datetime
3.5 sys
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Python基礎(七)--模塊和包
1 模塊
1.1 什么是模塊
模塊是一個Python文件,該文件包含相關的定義與語句(類,函數,變量)。模塊具有名稱,名稱與文件的名稱一致。
使用模塊的好處:
①通過劃分若干個模塊,將項目程序進行明確的劃分,從而將復雜問題簡單化,同時,也能夠進行更加合理的分工,有利于協作式開發程序。
②模塊提供獨立的命名空間,可以解決命名上的沖突。不同的模塊中,定義相同名稱的變量,不會產生命名沖突
③模塊可以實現良好的重用性,在多人間實現共享。
1.2 模塊的使用
每個項目可以劃分為多個模塊。但模塊與模塊之間,不可能都是完全孤立的。一個模塊很可能需要與其他的一個(或多個)模塊進行交互,因此,當需要在一個模塊中使用其他模塊定義的名稱(函數,類,變量等),則需要首先導入該模塊,然后通過模塊名.名稱進行訪問。
(1)導入模塊
使用import對模塊進行導入:import 模塊
我們還可以一次導入多個模塊:import 模塊1,模塊2……
當導入模塊時,該模塊內的語句就會得到執行,但只會執行一次,即重復導入模塊不會多次執行。當模塊作為腳本執行時(使用python命令在命令行執行),模塊中的語句也會得到執行。按照慣例,模塊導入語句寫在模塊的最上方。
當導入模塊后,我們就可以使用模塊中所定義的名稱,格式為:模塊名.名稱
①訪問模塊:可以將其他模塊中定義的名稱(全局命名空間中的名稱)直接導入到當前模塊的命名空間,這樣,我們就可以直接通過名稱訪問,而無需使用模塊名限定。格式如下:from 模塊 import 名稱1,名稱2……
注意:這種導入方式要稍加留意,因為如果當前模塊中也存在同樣名稱的定義,就會造成名稱的沖突,也就是名稱會重新綁定后來的對象。
②模塊沖突:假設不考慮名稱的沖突,只考慮訪問的便捷性,使用from import的方式確實是不錯的選擇。但是,如果我們要使用該模塊中定義的很多名稱,一個個的導入可能會有些繁瑣,此時,我們可以使用批量導入:from 模塊 import *
這樣就會將模塊中除了以_開頭的所有名稱導入到當前模塊的命名空間。然而,這種方式會導入很多名稱,容易造成命名沖突,盡可能少用。
注意:在Python中一切都是對象,模塊也是一個對象 。使用import導入模塊的時候,模塊定義的語句就會執行
(2)模塊別名
當導入模塊(或模塊中的名稱)時,我們可以使用as為模塊(或模塊中的名稱)指定別名。語法如下:
? ? ? import 模塊名?as 模塊別名
? ? ? from 模塊名?import 名稱 as 名稱別名
這樣,我們就可以通過別名來訪問模塊(或模塊中的名稱)。但是,一旦指定別名后,原模塊名(或原模塊中的名稱)將不再可用。
別名的好處:①解決名稱沖突,②使用簡短的別名,減少輸入量。
(3)隱藏模塊數據
因為使用import *的語法會在當前命名空間增加很多名稱,為了減少import *所造成的影響(名稱沖突),我們可以有選擇性的隱藏模塊的數據,進而限制使用import *時,名稱的導入。
隱藏模塊數據可以采用兩種方式:①將名稱以下劃線(_)開頭。②定義__all__變量。
上面兩種隱藏方式僅是限制使用import *語法導入的名稱,并不是表示該名稱無法在模塊外訪問。使用import其他方式導入,還是能夠在模塊外進行訪問的。他們的順序為,會首先檢查__all__變量,如果存在,會將__all__中指定的名稱導入到當前的命名空間。如果不存在,則會將除下劃線(_)開頭的名稱導入到當前的命名空間。即__all__中即使指定以下劃線(_)開頭的名稱,該名稱依然可以成功導入到當前的命名空間中。
①將名稱以下劃線(_)開頭:如果模塊中定義的名稱以_開頭,則在使用import *語法時,這些名稱不會導入到當前模塊的命名空間中,即當前模塊無法直接訪問該名稱。
②定義__all__變量:如果使用from 模塊 import *的語法,則默認情況下會導入模塊中除_開頭的所有名稱,這容易與當前模塊的命名造成沖突。我們可以定義__all__變量來限制導出名稱的數量。當在模塊中定義__all__變量時,該變量的值為一個字符串列表,只有列表中指定的名稱才會導入到當前命名空間。
# 為了減少命名沖突,可以限制from 模塊名 import * 的導入模塊 # 顯示的方式有兩種:1.名稱前使用_ 2.在模塊內定義__all__關聯一個str類型的列表(列表中指定所有能用*導入的名稱) # 它們的順序為:先查看__all__名稱,如果該名稱存在,則導入列表中所有的元素指定的名稱,如果不存在,則導入 # 該模塊下所有未使用_開頭的名稱,這意味著如果__all__中指定了_開頭的名稱,一樣可以導入 from lead import * print(a,b,_c) print(__name__) print("lead模塊執行了") # 指定可以由from import * 導入的名稱 __all__ = ["a","b","_c"] a = "在lead模塊中定義的變量" def b():print("在lead模塊中定義的函數") _c = "不會被from import * 語法導入" d = "不在__all__列表內"print("lead模塊的__name__名稱:" + __name__)(4)__name__
在編寫模塊時,我們可能需要對當前模塊的功能進行測試。當我們在其他模塊中導入當前模塊時,測試內容就會得到執行,這并不是期望的。因此,我們不得不將其去掉或者注釋??墒?#xff0c;以后還需要再寫入新的測試代碼來驗證新增功能的正確性,如此反復,非常不方便。
解決方法是:我們可以通過__name__屬性來獲取模塊的名稱。模塊會在兩種情況下執行:①當模塊由其他模塊導入時;②當模塊作為腳本,在命令行使用python?文件名.py執行時。兩種執行方式,通過__name__獲取的模塊名稱是不一致的。當模塊由其他模塊導入時,模塊的名稱就是文件的名稱,而模塊作為腳本執行時,模塊的名稱為__main__。因此,我們可以據此獲取模塊執行的方式。
# __name__名稱 # 作為腳本運行的模塊,__name__固定返回__name__ # 作為被其他模塊導入而運行時,__name__返回的就是當前模塊的名稱 # 為了方便測試,我們可以將測試語句寫在:if __name__ == "__name__"中 def is_even_number(number):return number % 2 == 0 # 如果當前模塊是作為腳本而執行沒說明在測試該模塊的功能,測試語句得到執行 if __name__ == "__name__":print(is_even_number(5))print(is_even_number(6))?
1.3 模塊的搜索路徑
當我們導入模塊時,解釋器會按照如下順序搜索:
①內置與解釋器中的模塊,如sys,math等;
②作為腳本執行的模塊所在路徑;
③PYTHONPATH環境變量指定的路徑,如果該環境沒有設置則忽略;
④Python安裝相關路徑,這包含Python語言的內建模塊(os, random模塊),以及安裝的第三方模塊(beautifulsoup,numpy模塊)所在的路徑等。
可以通過sys模塊的path屬性獲得路徑信息。path的值(列表類型)就是由后三項按順序組成的(后三項路徑的并集)。解釋器會在這些路徑中尋找模塊名.py文件。
解釋器會按順序進行查找,以先找到的為準。因此,如果在不同的路徑中都存在滿足條件的模塊,會以先找到的為準。
1.4 模塊的緩存
導入模塊時,Python會緩存所加載模塊編譯后的版本。從實現的角度,就是將導入模塊的文件(*.py)編程成字節碼文件(*.pyc)。這樣在下次運行時,就會檢查字節碼所對應的源文件在編譯過后是否經過修改,即字節碼文件是否是對應源文件的最新版本。如果不是最新版本,則會對源文件重新進行編譯。如果已經是最新版本,則會從字節碼文件中讀取信息,這樣可以加快模塊的加載速度。
編譯的字節碼(*.pyc)文件是平臺無關的,即不管在什么平臺,只要Python源文件的內容相同,編譯過后的字節碼文件也相同。字節碼文件會保存在與作為腳本運行文件相同路徑下的__pycache__目錄中。格式為“模塊名.解釋器-版本.pyc”,例如,假設導入的模塊為test,解釋器為CPython3.6,則字節碼文件名為“test.cpython-36.pyc”。
注意:①緩存字節碼文件只是可以提供模塊加載的速度,并不會提高模塊運行的速度。
②只有導入的模塊才會生成字節碼文件,作為腳本運行的文件不會生成字節碼文件。
③字節碼文件可以脫離源文件而運行。
2 包
2.1 什么是包
包類似于操作系統中的文件夾(目錄,路徑)
包的作用:①提供對模塊的分類管理
②提供獨立的命名空間,可以解決模塊的命名沖突
2.2 包的使用
(1)導入包
目錄與子目錄,目錄與文件之間,使用特定的分隔符進行分隔。例如,Windows操作系統使用“\”,Linux系統使用“/”。同樣,包也可以含有子包,包與包,包與模塊之間使用“.”來分隔。可以通過import來導入包,或者是導入包中的模塊。與之前導入模塊的語法是相同的,例如:
import 包名
import 包名.模塊名
from 包名 import 模塊名
from 包名.模塊名 import 名稱
上面導入包的方式,我們稱為絕對導入,此外,我們也可以進行相對導入。我們使用“.”來表示當前模塊所在的包,使用“..”來表示當前模塊所在包的父包(上級包)。例如:
from . import 名稱
(2)__init__.py
在每一個包中,應該同時配有一個__init__.py文件(模塊)。它的作用如下:
①該文件用來標記,當前的路徑是一個包,而不是普通的目錄,以避免目錄名與模塊名造成混淆
②該文件為包的初始化模塊,當導入包,或者導入包的子包(子模塊)時,該模塊會自動執行。因此,我們可以在__init__.py中編寫一些包的初始化語句;
③在__init__.py中定義的,具有全局作用域的名稱,可以使用包名.名稱進行訪問(這些名稱就會成為包(對象)的屬性)
(3)__all__
我們可以在__init__.py中定義__all__變量,來控制導入哪些名稱,這與模塊中的定義的__all__變量意義相同,也是一個字符串的列表類型,指定能夠導入的名稱。
?
3 常用模塊
3.1 math
math模塊提供了與數學計算相關的功能。常用的功能如下:
| 名稱 | 描述 |
| pi | 返回圓周率的值 |
| e | 返回數學常數 |
| ceil(x) | 返回大于等于x的最小整數(向上取整) |
| floor(x) | 返回小于等于x的最大整數(向下取整) |
| exp(x) | 返回e的x次冪,相當于math.e**x |
| pow(x,y) | 返回x的y次冪,相當于x**y |
| log(x[,base]) | 返回基于base為底,x的對數。base默認為e |
| fabs(x) | 返回x(視為float類型)的絕對值 |
| factorial(x) | 返回x的階乘,x需要是int類型,或者是小數點為0的浮點類型,并且不能為負。 |
| fmod(x,y) | 返回x與y取余的結果。注意:x?% y是取模,二者結果可能是不同的。 |
| fsum(itreable) | 返回可迭代對象中每個值累計求和后的結果。 |
| gcd(x,y) | 返回x與y的最大公約數。x與y需要是整數類型 |
| sqrt(x) | 返回x的平方根 |
3.2 random
random模塊提供生成隨機數的功能(偽隨機數)。常用功能如下:
| 名稱 | 描述 |
| random() | 返回一個0~1之間的浮點數,包括0不包括1 |
| randint(a,b) | 返回一個a~b之間的整數,包括a與b |
| randrange(stop)/ randrange(start,stop[.step]) | 參數與range函數的意義相同,相當于從相同參數的range函數可能產生的值中,隨便選擇一個 |
| uniform(a,b) | 返回a與b之間的浮點數,包括端點 |
| choice(seq) | 從seq(可迭代對象)中隨機選擇一個元素,如果序列為空,則產生錯誤 |
| choices(population, weights=None, *, cum_weights=None, k=1) | 從population(可迭代對象)中選擇k個元素,放入一個列表并返回。如果提供了weights(權重)或cum_weights(累積權重),則元素的選擇概率會根據權重(累積權重)決定。權重與累積權重不能同時指定,因為權重內部會轉換成累積權重,這樣會造成不一致。如果沒有指定權重與累積權重,則各個元素的選擇概率相同。 |
| sample(population, k) | 從population(可迭代對象)中選擇k個不同的元素,返回元素組成的列表。 |
| shuffle(x[, random]) | 對x(序列)進行洗牌(隨機分配每個元素的位置)。random是一個可選的生成隨機數的函數,函數的返回值為[0, 1),默認使用random模塊的random函數。 |
3.3 time
time模塊提供關于時間的操作
| 名稱 | 描述 |
| timezone | 返回與UTC時間(世界標準時間)相差的秒數。正數表示晚于UTC時間,負數表示早于UTC時間。 |
| time() | 返回從新紀元(1970-01-01 00:00:00)到當前時間走過的秒數。 |
| localtime([seconds]) | 返回從新紀元走過seconds(秒數)后的時間。返回類型為time.struct_time類型(tuple的子類),如果seconds沒有指定,則默認表示當前時間。該時間顯示的是本地時間,要考慮對應的時區。例如,北京時間為東八區,比UTC時間早8小時,因此,需要在最后轉換的時間上加上8小時。struct_time是一個命名元組(可以通過屬性名訪問,也可以通過索引訪問) |
| gmtime([seconds]) | 與localtime([seconds])的用法相同,只是返回的是UTC時間,而不是本地時間。 |
| mktime(tuple) | 將tuple(本地時間的元組)轉換為從新紀元到元組指定時間走過的秒數。與localtime([seconds])函數正好是相反的 |
| asctime([tuple]) | 將tuple(時間元組)轉換成字符串(str)的表示形式。如果沒有提供tuple參數,則使用localtime()函數返回的元組(當前的本地時間)。 |
| ctime([tuple]) | 將從新紀元走過的毫秒數轉換為本地時間。該函數相當于這樣調用:asctime(localtime(seconds))。如果seconds參數沒有指定,則使用time()函數返回的秒數。 |
| sleep(seconds) | 使當前程序暫停執行參數指定的時間。seconds可以是小數。 |
| clock() | 在Unix / Linux系統,該函數返回CPU的計算時間。在Windows操作系統,該函數第一次調用,返回CPU的計算時間,從第二次調用開始,返回距離第一次調用該函數所經歷的時間。CPU的計算時間不包括調用sleep暫停的時間,因為在暫停時,CPU沒有工作。因為該函數在不同操作系統上行為的不一致性,從Python3.3起,已經不建議使用,取而代之的是使用perf_counter()函數或者是 process_time()函數。 |
| perf_counter() | 返回精準的性能計數器,可以用來測試短時間的時間差。該時間包含調用sleep函數暫停的時間。該函數返回值所基于的時間點是不確定的,我們不能當成系統時鐘來使用,但是可以多次調用該函數,計算一段程序執行的時間差。 |
| process_time() | 返回當前進程下,系統以及用戶的CPU計算時間。該時間不包含調用sleep函數暫停的時間。 |
| strftime(format[, tuple]) -> string | 將tuple(時間元組)轉換成format參數指定的格式的字符串。如果tuple沒有指定,則使用localtime()函數返回的元組。format中可以含有特殊占位符,將使用元組中特定值進行替換,非特殊占位符會原樣顯示。 |
| strptime(string, format) -> struct_time | 按照format指定的格式,將string(時間格式字符串)解析為時間的元組。format的格式與strftime函數的format格式相同 |
struct_time類的格式
| 索引 | 屬性名 | 說明 |
| 0 | tm_year | 年(四位數表示)。 |
| 1 | tm_mon | 月份(1 ~?12)。 |
| 2 | tm_mday | 日(1?~ 31)。 |
| 3 | tm_hour | 小時(0 ~?23)。 |
| 4 | tm_min | 分(0 ~ 59)。 |
| 5 | tm_sec | 秒(0 ~ 61),60用來表示閏秒(跳秒),是對世界時間的一種調整。61因為歷史原因所保留。 |
| 6 | tm_wday | 星期(0 ~ 6),周一為0,周日為6。 |
| 7 | tm_yday | 年度的第幾天(1 ~ 366)。 |
| 8 | tm_isdst | 是否支持DST(daylight saving time),即夏令時(日光節約時間)。部分國家在天亮早的夏季,將時鐘向前調整一小時,從而可以節約照明資源??赡苤禐?(不生效)、1(生效)或-1(未知)。 |
占位符
| 占位符 | 說明 |
| %Y | 年份(四位數字)。 |
| %y | 年份(兩位數字)。 |
| %m | 月份(01 ~ 12)。 |
| %d | 日(01 ~ 31)。 |
| %H | 24小時制(00 ~ 23) |
| %I | 12小時制(00 ~ 12) |
| %M | 分鐘(00 ~ 59)。 |
| %S | 秒(00 ~ 61)。 |
| %w | 周期幾(0 ~ 6),周日為0。注意,與tm_wday的表示不一致。 |
| %j | 年度的第幾天(001 ~ 366)。 |
| %W | 年度的第幾周(00 ~ 53),星期一視為一周的第一天。在年度第一個周一之前的天視為第0周。 |
| %U | 年度的第幾周(00 ~ 53),星期日視為一周的第一天。在年度第一個周日之前的天視為第0周。 |
| %z | 當前時區與UTC的時間差。格式為+HHMM(當前時區早于UTC)或-HHMM(當前時區晚于UTC)。 |
| %Z | 時區名稱。 |
| %a | 本地星期的簡寫名。 |
| %A | 本地星期的全名。 |
| %b | 本地月份的簡寫名。 |
| %B | 本地月份的全名。 |
| %c | 本地日期與時間的恰當表示。 |
| %x | 本地日期的恰當表示。 |
| %X | 本地時間的恰當表示。 |
| %p | 顯示AM或PM(或其本地等效的其他表示方式)。 |
| %% | %的轉義。 |
3.4 datetime
datetime模塊提供date,time,datetime,timedelta等類,供我們對日期與時間進行操作。與time模塊相比,datetime模塊還額外增加了日期的加減與比較運算。
(1)date類
date類提供針對日期(不含時間)的操作。
| 構造器 | date(year, month, day):用來創建參數指定日期的date對象。year指定年,month指定月,day指定日。 |
| 實例屬性 | year / month / day:返回年?/ 月 / 日 |
| 類屬性 | max / min:最早的?/ 最晚的date對象; resolution:類屬性兩個不同date對象的最小差距值 |
| 實例方法 | ctime():返回特定格式的字符串來表示日期; replace(year=self.year, month=self.month, day=self.day):返回新的date對象,值為使用當前參數替換之后的結果。year指定要替換的年,month指定要替換的月,day指定要替換的日; timetuple?():返回time.struct_time對象,類似于time.localtime()返回的結果; weekday():返回當前日期是星期幾(0 ~ 6)。星期一返回0,星期日返回6。 toordinal():返回當前日期的序數。1年1月1日序數為1,1年1月2日序數為2,以此類推; strftime(format):根據format指定的格式,顯示當前的日期對象。 |
| 類方法 | today():類方法,返回當前的日期。 fromtimestamp(timestamp):從參數指定的timestamp(時間戳,即從新紀元走過的秒數)中創建date對象。 fromordinal(ordinal):根據參數指定的ordinal(序數)創建date對象。 |
(2)time類
time類提供針對時間的操作
| 構造器 | time(hour=0, minute=0, second=0, microsecond=0):創建參數指定的time對象。hour指定小時,minute指定分鐘,second指定秒,micorsecond指定微秒。 |
| 實例屬性 | hour / minute?/ second / microsecond:返回小時 / 分鐘 / 秒 / 微秒 |
| 類屬性 | max / min:最早的?/ 最晚的time對象; resolution:類屬性兩個不同time對象的最小差距值 |
| 實例方法 | replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond):創建一個新的time對象,值為參數指定的值替換之后的結果。hour指定要替換的小時,minute指定要替換的分鐘,second指定要替換的秒,microsecond指定要替換的微秒。 strftime(format):根據format指定的格式,顯示當前的時間對象。 |
(3)datetime類
datetime類提供針對日期與時間的操作,相當于是date與time兩個類功能的并集。
| 構造器 | datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0):用來創建參數指定日期的datetime對象。year,month與day三個參數是必須的。 |
| 實例屬性 | year / month / day:返回年?/ 月 / 日 hour / minute?/ second / microsecond:返回小時 / 分鐘 / 秒 / 微秒。 |
| 類屬性 | max / min:最早的?/ 最晚的datetime對象; resolution:類屬性兩個不同datetime對象的最小差距值 |
| 實例方法 | date():返回date對象,年,月,日與datetime對象的年,月,日相同。 time():返回time對象,時,分,秒,微秒與datetime對象的時,分,秒,微秒相同。 ctime():返回特定格式的字符串來表示日期時間。 replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond):返回新的datetime對象,值為使用當前參數替換之后的結果。 timetuple?():返回time.struct_time對象,類似于time.localtime()返回的結果。 weekday():返回當前日期是星期幾(0 ~ 6)。星期一返回0,星期日返回6。 toordinal():返回當前日期的序數。1年1月1日序數為1,1年1月2日序數為2,以此類推。 strftime(format):根據format指定的格式,顯示當前的日期時間對象。 ? |
| 類方法 | today():返回當前的日期與時間。 now():返回當前的日期與時間,與today方法類似。 utcnow():返回當前的日期與時間轉換為UTC之后的結果。 fromtimestamp(timestamp):從參數指定的timestamp(時間戳,即從新紀元走過的秒數)中創建datetime對象。 utcfromtimestamp(timestamp):從參數指定的timestamp(時間戳,即從新紀元走過的秒數)中創建UTC?datetime對象。 fromordinal(ordinal):根據參數指定的ordinal(序數)創建datetime對象。 strptime(date_string, format):根據給定的date_string(日期時間字符串),按照format指定的格式進行解析,返回datetime對象。 |
(4)timedelta類
timedelta對象用來表示持續時間,可以用來進行日期與時間的加減。
構造器;timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0):根據給定的參數,創建timedelta對象,表示持續時間。持續時間為各參數累計相加。
兩個datetime.datetime類型相減 或兩個 datetime.date類型相減 的結果就是datetime.timedelta類型
3.5 sys
sys模塊提供一些與解釋器相關的功能。sys提供的屬性很多,不過多數并不常用,常見屬性如下:
| 名稱 | 描述 |
| argv | 返回一個列表,列表的第一個元素為命令行運行的文件名稱,往后的每個元素為命令行在文件名稱后面傳遞的每一個參數。當我們要進行一些全局性,系統相關的配置時,就可以使用命令行來傳遞參數。所傳遞的參數就可以通過argv來進行獲取。 |
| version | 返回Python的版本信息 |
| copyright | 返回Python的版權信息 |
| path | 返回模塊的搜索路徑 |
| float_info | 返回浮點類型(float)的相關信息 |
| platform | 返回操作系統信息 |
| exit() | 退出Python解釋器,終止程序的執行 |
| getsizeof(object) | 返回object(對象)的大小(以字節為單位) |
| setrecursionlimit(n) | 設置最大遞歸的深度 |
?
?
總結
以上是生活随笔為你收集整理的Python基础(七)--模块和包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机专业配置笔记本,学计算机专业的买什
- 下一篇: python导入gif_Python之G