模塊 Modulepython
什麼是模塊:編程
一、模塊是一個包含有一系列數據,函數,類等組成的程序組json
二、模塊是一個文件,模塊文件名一般以.py結尾dom
做用:ide
一、讓一些相關數據,函數,類等有邏輯的組織在一塊兒,使邏輯結構更加清晰模塊化
二、模塊中的數據,函數和類等可提供給其它模塊或程序使用函數
模塊的分類:(同一個模塊在不一樣的操做系統下可能數不一樣類型的模塊)ui
一、內置模塊(builtins),通常是用C語言來寫的,在解析器的內部能夠直接使用。模塊說明中有builtins關鍵字this
二、標準庫模塊,安裝python時已經安裝且可直接使用。spa
三、第三方模塊(一般爲開源),須要本身安裝
四、用戶本身完成的模塊(能夠做爲其餘人的第三方模塊)
模塊的導入語句
import語句
語法:import 模塊名1 [as 模塊新名1][,模塊名2[ as 模塊新名2]],....
做用:將某模塊總體導入到當前模塊
用法:模塊.屬性名
dir(obj)函數返回模塊全部屬性的字符串列表
help(obj)能夠查看模塊相關的文檔字符串
from import語句
語法: from 模塊名 import 模塊屬性名1[as 屬性新名1] [,模塊屬性名2[as 屬性新名2],....]
做用:將模塊內的一個或多個屬性導入到當前模塊的做用域
說明:屬性是模塊內的全部全局變量
from import * 語句 (通常不用)
語法:from 模塊名 import *
做用:將某模塊的全部屬性都導入到當前模塊
dir函數:
dir([對象])返回一個字符串列表
做用:一、若是沒有參數調用,則返回當前做用域內的全部變量的列表
二、若是給定一個對象做爲參數,則返回這個對象的全部變量的列表
1)對於一個模塊,返回這個模塊的所有屬性
2)對於一個類對象,返回這個類對象的全部變量,親遞歸基類對象的全部變量
3)對於其它對象,返回全部的變量,類變量,基類變量
變量:
math.e 天然對數的底e
math.pi 圓周率pi
函數:
math.ceil(x) 對x向上取整,好比x = 1.2 ,返回2
math.floor(x) 對x向下取整,好比x = 1.8 ,返回1
math.sqrt(x) 返回x的平方根
math.factorial(x) 求x的階乘
math.log(x,[base]) 返回以base爲底的x的對數,若是不給base,則以天然對數e爲底
math.log10(x) 求以10爲底x的對數
math.pow(x,y) 返回x**y
math.fabs(x) 返回浮點數x的絕對值,好比x = -1,返回1.0
角度degrees和弧度radians互換
math.degrees(x) 將弧度x轉換爲角度
math.radians(x) 將角度x轉換爲弧度
三角函數,下面的x都是以弧度爲單位的
math.sin(x) 返回x的正弦
math.cos(x) 返回x的餘弦
math.tan(x) 返回x的正切
math.asin(x) 返回x的反正弦(返回值爲弧度)
math.acos(x) 返回x的反餘弦(返回值爲弧度)
math.atan(x) 返回x的反正切(返回值爲弧度)
此模塊提供了時間相關的函數,且一直可用
時間簡介
一、公元紀年是從公元0000年1月1日0時開始的
二、計算機元年是從1970年1月1日0時開始的,此時間爲0,以後每過一秒時間+1
三、UTC時間(Coordinated Universal Time )是從Greenwich時間開始計算的,UTC時間不會因時區問題而產生錯誤
四、DST陽光節約時間(Daylight Saving Time ),又稱夏玲時,是一個通過日照時間修正後的時間(中國已經不用了)
時間元組
時間元組是一個9個整型元素組成的,這九個元素自前至後一次爲
一、四位的年(如:1992)
二、月(1-12)
三、日(1-31)
四、時(0-23)
五、分(0-59)
六、秒(0-59)
七、星期幾(0-6,週一是0)
八、元旦開始日(1-366)
九、夏令時修時間(-1,0 or 1),對中國來講是0
注:若是年份小於100,則會自動轉換爲加上1900後的值
變量
time.altzone 夏令時時間與UTC時間差(秒爲單位),-32400秒
time.daylight 夏令時校訂時間,在中國爲0
time.timezone 本地區時間與UTC時間差(秒爲單位),-28800秒
time.tzname 時區名字的元組,第一個名字爲未經夏令時修正的時區,第二個名字爲經夏令時修正後的時間("CST","CST")
注:CST爲中國標準時間(China Standard Time UTC+8:00)
函數:
time.time() 返回從計算機元年至當前時間的秒數的浮點數(UTC時間爲準)
time.sleep(secs) 讓程序按給定秒數的浮點數睡眠一段時間
time.gmtime([secs]) 用給定秒數轉換爲用UTC表達的時間元組(默認返回當前時間元組)
time.asctime([tuple]) 將時間元組轉爲日期時間字符串,默認爲當前時間
time.ctime([secs]) 將時間戳轉發爲日期時間字符串,默認是當前時間
time.mktime(tuple) 將本地日期時間元組轉爲新紀元秒數時間(UTC爲準)
time.localtime([secs]) 將UTC秒數時間轉爲日期元組(以本地時間爲準),默認爲當前時間
注:time.mktime(time.localtime()) - time.mktime(time.gmtime()) = 28800.0 說明當時時間比UTC時間早8個小時
time.clock() 返回處理器時間,3.0版本開始已經廢棄,改爲time.process_time()
time.strftime(formt[,tuple]) 返回可讀字符串時間,格式有參數format決定。
time.strptime()
time.tzset()
python中時間日期格式化符號
%y 表示兩位數的年份(00-99)
%Y 表示四位數的年份(0000-9999)
%m 月份(01-12)
%d 月內中的一天(0-31)
%H 24小時制小時數(0-23)
%I 12小時制小時數(01-12)
%M 分鐘數(00-59)
%S 秒數(00-59)
%a 本地簡化星期名稱
%A 本地完整星期名稱
%b 本地簡化月份名稱
%B 本地完整月份名稱
%c 本地相應的的日期表示和時間表示
%j 年內的一天(001-366)
%p 本地A.M.或P.M.的等價符
%U 一年中的星期數(00-53)星期日爲星期的開始
%w 星期(0-6),星期天爲星期的開始
%W 一年中的星期數(00-53)星期一爲星期的開始
%x 本地相應的日期表示
%X 本地相應的時間表示
%Z 當前時區的名稱
%% %號自己
import time print(time.localtime())#time.struct_time(tm_year=2018, tm_mon=7, tm_mday=19, tm_hour=0, tm_min=44, tm_sec=5, tm_wday=3, tm_yday=200, tm_isdst=0) print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))#2018-07-19 00:44:05 print(time.strftime("%y-%m-%d %I:%M:%S",time.localtime()))#18-07-19 12:44:05 print(time.strftime("%a-%A-%b-%B-%c-%j-%p-%U-%w-%W-%x-%X-%Z-%%",time.localtime())) # Thu-Thursday-Jul-July-Thu Jul 19 00:44:05 2018-200-AM-28-4-29-07/19/18-00:44:05-?D1¨²¡À¨º¡Á?¨º¡À??-% # a A b B c j p U w W x X Z %
此模塊所有是運行時系統相關的信息
做用:用於獲取和設置與系統相關的信息
變量
sys.path 返回模塊的搜索路徑,path[0]是當前腳本程序的路徑,初始化時使用pythonPath環境變量的值
sys.modules 返回已加載模塊的字典,字典的鍵爲模塊名,值爲已加載的模塊
sys.version 返回python版本信息的字符串:'3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]'
sys.version_info 返回python版本信息的命名元組:sys.version_info(major=3, minor=5, micro=4, releaselevel='final', serial=0)
sys.platform 操做系統平臺的名稱信息(Win32)
sys.argv 命令行參數argv[0]表明當前腳本程序的路徑名,綁定用戶啓動程序時命令參數的列表
sys.copyright 得到python版權相關信息
sys.builtin_module_names 得到python內建模塊的名稱(字符串元組)
標準輸入輸出時會用到
sys.stdin 標準輸入文件對象,多用於input()
sys.stdout 標準輸出文件對象,多用於print()
sys.stderr 標準錯誤輸出文件對象,用於輸出錯誤信息
函數:
sys.exit([arg]) 退出程序,正常退出時sys.exit(0)
sys.getrecursionlimit() 獲得遞歸嵌套層次限制(棧的深度)
sys.setrecursionlimit(n) 獲得和修改遞歸嵌套層次限制(棧的深度),你表明遞歸的次數,腳本中止,則這個限制還原
自定義模塊模塊名必須符合「標識符」的命名規則(同變量名),模塊有各自獨立的做用域
模塊化編程的優勢:
一、有利於多人合做開發
二、使代碼更易於維護
三、提升代碼的複用率
四、有利於解決變量名衝突問題
import 語句 搜索模塊的路徑順序
一、搜索程序運行時的路徑(當前路徑)
二、sys.path提供的路徑
三、搜索內置模塊
說明:sys.path是一個存儲模塊搜索路徑的列表
一、能夠把自定義的模塊放在相應的路徑下能夠導入
二、能夠把本身模塊的路徑添加在sys.path列表中
模塊的加載過程:
一、在模塊導入時,模塊的全部語句會執行
二、若是一個模塊已經導入,則再次導入時不會從新執行模塊內的語句
模塊的從新加載:
當已經被導入的模塊內容被修改後,能夠經過從新執行當前的程序從新加載,或者經過import imp;imp.reload(模塊名)的方法從新加載
模塊被導入和執行的過程
一、先搜索相關的路徑找到模塊(.py)
二、判斷是否有此模塊對應的.pyc文件,若是存在pyc文件且比.py文件新,則直接加載.pyc文件
三、不然用.py文件生成.pyc文件後再進行加載
pyc 模塊的編譯文件:
mymod1.py----編譯(compile)------→mymod1.pyc------解釋執行-----→python3
模塊的屬性
屬性的實質是變量(是模塊內的全局變量)
模塊內預置的屬性
__doc__屬性
做用:用來綁定模塊的文檔字符串
模塊內第一個沒有賦值給任何變量的字符串爲模塊的文檔字符串,(若是沒有賦值的字符串出如今第二個語句,則文檔字符串爲空)
__file__屬性
用來綁定模塊對應的文檔路徑名
一、對於內建模塊,不綁定路徑(沒有__file__屬性)
二、對於其它模塊,綁定路徑名的字符串(相對路徑:模塊名.py)
__name__屬性
此屬性用來記錄模塊的自身名字
做用:一、記錄模塊名
二、用來判斷是否爲主模塊(最早運行的模塊)
說明:一、當此模塊爲主模塊時,__name__綁定"__main__"
二、當此模塊不是主模塊時,此屬性綁定模塊名
模塊的__all__列表(不屬於模塊的屬性)
模塊中的__all__列表是一個用來存放可導出屬性的字符串列表
做用:當用from import * 語句導入時,只導入__all__列表內的屬性,若是沒有次列表則模塊的全部屬性都被導入
不會影響import 模塊名 和 from 模塊名 import 屬性名 兩個語句的導入
模塊的隱藏屬性:
模塊中以"_"下劃線(不只僅是單下劃線,多個下劃線)開頭的屬性,在from import *語句導入時,將不被導入,一般稱這些屬性爲隱藏屬性。
若是該屬性被放入__all__列表中,將會被導入
做用:用於模擬或生成隨機輸出的模塊
函數(import random as R)
R.random() 返回一個[0,1)之間的隨機實數
R.randint(a,b) 返回一個 [a~b]之間的隨機整數,包括a,b
R.uniform(a,b) 返回[a,b)區間內的隨機實數
R.randrange([start,] stop[,step]) 返回range(start,stop,step)中的隨機數
R.choice(seq) 從序列中返回隨機數
R.shuffle(seq, [,random]) 隨機指定序列的順序(亂序序列),函數的第二個參數表明必須傳入random模塊中無參的函數目前只有random函數,可使用 R.random代替,目前版本沒有什麼用
R.sample(seq,n) 從序列中選擇n個隨機且不重複的元素
import random L = [i for i in range(10)] L5 = random.sample(L,5) print(L) print(L5)
序列化:
咱們把對象(變量)從內存中變成可存儲的或傳輸的過程稱之爲序列化,反過來,把變量內容從序列化後的對象從新讀到內存中稱爲反序列化
說明:json不能講高級的對象序列化,好比:函數、類,若是要序列化函數 或者 類時須要使用pickle模塊
json中的函數:
一、dumps():序列化
二、loades():反序列化
import json dic = {'name':"xdl",'age':25} #將字典對象序列,使之變爲可存儲的對象 dic = json.dumps(dic) f = open('json_test','w') f.write(dic)
import json f = open('json_test','r') dic = f.read() #將讀出的數據反序列化,並讀入到內存中 dic = json.loads(dic) print(dic['name'])
pickle中的函數
一、dumps():序列化對象
二、loads():反序列化對象
import pickle def foo(): print('ok') #將字典對象序列,使之變爲可存儲的對象,是字節串,須要使用wb寫入 foo = pickle.dumps(foo) f = open('json_test','wb') f.write(foo) f.close()
import pickle def foo(): print('ok') f = open('json_test','rb') data = f.read() #將讀出的數據反序列化,並讀入到內存中 #反序列化以前要建立一個與讀取的函數名相同的函數 #不然會報錯:AttributeError: Can't get attribute 'foo' on <module '__main__' from ' # /home/tarena/PycharmProjects/xdl/module/pickle_load.py'> data = pickle.loads(data) data()
使用步驟:
一、獲取logger實例對象,若是參數爲空則返回root logger,
logger = logging.getLogger()
二、指定logger的格式
formatter = logging.Formatter('自定義格式')
三、建立具體的日誌handler,並將日誌格式添加處處理器上,包括文件日誌和終端日誌
1)文件日誌:
file_handler = logging.FileHandler('文件名稱.log')
file_handler.setFormatter(formatter)
2)終端日誌(在終端上顯示日誌信息)
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
四、設置日誌級別
logger.setLevel(日誌級別)
五、把日誌的handler對象添加到日誌對象logger中
logger.addHandler(file_handler)
logger.addHandler(console_handler)
六、寫日誌
七、移除日誌處理器
logger.removeHandler(file_handler)
logger.removeHandler(console_handler)
import logging import sys #一、獲取logger的實例,<Logger testlog (INFO)>,(INFO)是本身設置的日誌級別,若是不給參數,<RootLogger root (INFO)> logger = logging.getLogger('testlog') #二、指定logger的格式 formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') #三、建立具體的日誌handler,文件日誌,終端日誌 #3.一、文件日誌 file_handler = logging.FileHandler('testLog.log') file_handler.setFormatter(formatter) #3.二、終端日誌 console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(formatter) #四、設置日誌的級別,高於等於這個默認級別纔會被顯示 logger.setLevel(logging.INFO) #五、把日誌的handler添加到logger實例中 logger.addHandler(file_handler) logger.addHandler(console_handler) #六、寫日誌 logger.error("Test Error log") logger.info("Test info log") logger.debug("Test debug log") #七、清空日誌 logger.removeHandler(file_handler) logger.removeHandler(console_handler)
將日誌封裝成一個模塊
class LogerHelper: def __init__(self,name='LogerHelper',setLevel=logging.DEBUG): self.logger = logging.getLogger(name) self.formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s") self.file_handler = logging.FileHandler(name+'.log') self.file_handler.setFormatter(self.formatter) self.console_handler = logging.StreamHandler(sys.stdout) self.console_handler.setFormatter(self.formatter) self.logger.setLevel(setLevel) self.logger.addHandler(self.file_handler) self.logger.addHandler(self.console_handler) def writeLog(self,info,level='debug'): if level == 'critial': self.logger.critical(info) elif level == 'error': self.logger.error(info) elif level == 'warn': self.logger.warn(info) elif level == 'info': self.logger.info(info) elif level == 'debug': self.logger.debug(info) def removeLog(self): self.logger.removeHandler(self.file_handler) self.logger.removeHandler(self.console_handler) if __name__ == '__main__': logger = LogerHelper() logger.writeLog("hello world",'critial') logger.writeLog("hello world",'error') logger.writeLog("hello world",'warn') logger.writeLog("hello world",'info') logger.writeLog("hello world",'debug') logger.removeLog()
包是將模塊以文件夾的組織形式進行分組管理的方法(包比其它普通文件夾多一個__init__.py)
做用:將一系列模塊進行分類管理,有利於防止命名衝突,能夠在須要時加載一個或一部分模塊而不是所有模塊
__init__.py文件
常規包內必須存在的文件
__init__.py會在包加載時被自動調用
做用:一、編寫此包的內容
二、在內部填寫文檔字符串
三、在__init__.py內能夠加載此包所依賴的一些其它模塊
包的導入
用三條import語句能夠導入包(同模塊的導入規則)
import 包名 [as 包別名]
import 包名.模塊名 [as 模塊新名]
import 包名.子包名.模塊名
from 包名 import 模塊名 [as 模塊新名]
from 包名.子包名 import 模塊名 [as 模塊新名]
from 包名.子包名.模塊名 import 屬性名 [as 屬性新名]
from 包名 import *
from 包名.模塊名 import *
包的__init__.py內的__all__列表
做用:用來記錄此包中有哪些子包或模塊在用from 包 import * 語句導入時是否被導入
說明:__all__列表只對from import * 語句起做用,若是沒有此列表則,都不會被導入
包的相對導入
包的相對導入是指包內模塊的相互導入
語法:一、from 相對路徑包或模塊 import 屬性或模塊名
二、from 相對路徑或模塊 import *
相對路徑:
一、.表明當前目錄 如:a/b/c.py 其中.c.py表明b路徑
二、..表明上一級目錄
三、...表明上二級目錄
四、....依次類推
注:相對導入時不能超出包的外部,若是超出包的外部會報錯ValueError: attempted relative import beyond top-level package
包的加載路徑:
和模塊的加載路徑相同
一、當前文件夾
二、sys.path給出的路徑
什麼是錯誤:
錯誤是指因爲邏輯或語法等致使一個程序沒法正常執行的問題
特色:有些錯誤是沒法預知的
什麼是異常:
異常是程序出錯時標識的一種狀態,
當異常發生時,程序不會再向下執行,而轉去調用此函數的地方待處理錯誤並恢復爲正常狀態
做用:
一、通知上層調用者有錯誤產生須要處理
二、用做信號通知
try 語句的兩種語法
try - except 語句
語法:try:
可能觸發異常的語句
except 錯誤類型1 [as 變量1]:
異常處理語句1
except 錯誤類型2 [as 變量2]:
異常處理語句2
except(錯誤類型3,錯誤類型4,...)[as 變量3]:#前面必須是異常類型元組
異常處理語句3
...
except: #捕獲全部錯誤類型
異常處理語句other
else:
未發生異常時執行的語句,(try語句嵌套的try語句出現異常並被處理,也要執行,若是沒有被處理將交給外部try語句進行處理)
finally:
最終執行語句(無論有沒有發生異常都會執行該語句,發生異常沒有被處理一樣會執行該語句)
做用:嘗試捕獲異常,將程序轉爲正常狀態並繼續執行
說明:一、as 子句用於綁定錯誤對象的變量,能夠省略不寫
二、except子句能夠有一個或多個,但至少要有一個
三、else子句最多隻能有一個,也能夠省略不寫
四、finally子句最多隻能有一個,也能夠省略不寫
try-finally語句
語法:try:
可能觸發異常的語句
finally:
最終語句
說明:一、finally子句不能夠省略
二、必定不存在except子句
做用:一般try-finally語句來作觸發異常時必需要處理的事情,不管異常是否發生,finally子句都會執行
注:try-finally語句不會改變程序的(正常/異常)狀態
raise語句
做用:觸發一個錯誤,讓程序進入異常狀態
語法:一、raise 異常類型 :raise ZeroDivisionError
二、raise 異常對象:rasie ZeroDivisionError("被零除了...")
assert 語句(斷言語句)
語法:assert 真值表達式,錯誤數據(一般是字符串)
做用:當真值表達式爲False時,用錯誤數據建立一個AssertionError類型的錯誤,並進入異常狀態
相似於:if 真值表達式 == False:
raise AssertionError(錯誤數據)
小結:
接收錯誤消息:try- except
作必需要處理的事情的語句:try-finally
發錯誤消息的語句:一、raise 語句
二、assert 語句
爲何要用異常處理處理機制:
在程序調用層數較深時,向主調用函數傳遞錯誤信息須要用return語句層層傳遞比較麻煩,因此用異常處理機制
異常(高級)
回顧異常相關的語句:
try-exept 用來捕獲異常通知
try-finally 用來作必定要作的事情
raise 用來發生異常通知
assert 用來根據條件來發出AssertionError類型的異常通知
with語句:
語法:with 表達式1 [as 變量1],表達式2 [as 變量2]:
語句塊
做用:使用於對資源進行訪問的場合,肯定使用過程當中不論是否發生異常,都會執行必須的‘清理’操做,並釋放資源
如:文件使用後自動關閉,線程中鎖的自動獲取和釋放等
說明:可以用於with語句進行管理的對象必須是環境管理器
'''此示例示意用try-except 和 try-finally 組合來對文件進行操做''' def read_from_file(filename="info.txt"): try: f = open(filename) try: print("正在讀取文件") n = int(f.read()) print("n=",n) finally: f.close() print("文件已經關閉") except OSError: print("文件打開失敗") read_from_file()
環境管理器:
一、類內有__enter__ 和 __exit__實例方法的類被稱爲環境管理器
二、能用with語句管理的對象必須是環境管理器
三、__enter__方法將在進入with語句時被調用,並返回由as變量管理的對象
四、__exit__方法將在離開with語句時被調用,且能夠用參數來判斷在離開with語句時是否有異常發生並作出相應的處理
contextlib,給咱們提供了一個裝飾器,只要按照它的代碼協議來實現函數內容,就能夠將這個函數對象變成一個上下文管理器
使用環境管理器(上下文管理器)的好處
1.提升代碼的複用率
2.提升代碼的優雅度
3.提升代碼的可讀性
import contextlib @contextlib.contextmanager def open_func(file_name): #__enter__方法 print('openfile',file_name,'in __enter__') file_handler = open(file_name,'r') #在被裝飾的函數中,必須是一個生成器,而yield以前的代碼至關於__enter__,以後的代碼至關於__exit__ try: yield file_handler except Exception as e: print(e) finally: print('closefile',file_name,'in __exit__') file_handler.close() if __name__ == "__main__": with open_func('aa.txt') as f: print(f) 1 / 0
def read_from_file(filename="info.txt"): try: with open(filename) as f: print("正在讀取文件") n = int(f.read()) print("n=",n) print("文件已經關閉") except OSError: print("文件打開失敗") read_from_file()
'''此示例示意環境管理器的定義及使用''' class A: def __enter__(self): print("已經進入with語句") return self #返回的對象將由as 綁定 def __exit__(self,exc_type,exc_val,exc_tb): '''此方法會在退出with語句時自動調用 exc_type在沒有異常時爲None,在出現異常時爲綁定異常類型 exc_val在沒有異常時爲None,在出現異常時綁定錯誤對象 exc_tb在沒有異常時爲None,在出現異常時綁定traceback(跟蹤)''' if exc_type is None: print("正常離開with語句!") else: print("異常離開with語句!") print("異常類型是:",exc_type) print("錯誤對象是",exc_val) print("traceback是:",exc_tb) with A() as a: print("我是with語句內的一條語句") int(input("輸入一個數:")) # 已經進入with語句 # 我是with語句內的一條語句 # 輸入一個數:aa # 異常離開with語句! # 異常類型是: <class 'ValueError'> # 錯誤對象是 invalid literal for int() with base 10: 'aa' # traceback是: <traceback object at 0x7f443a0e2748> # Traceback (most recent call last): # File "02_enter_exit.py", line 24, in <module> # int(input("輸入一個數:")) # ValueError: invalid literal for int() with base 10: 'aa'