猪行天下之Python基础——10.1 Python常用模块(上)
內(nèi)容簡述:
- 1、time和datetime模塊
- 2、logging模塊
PS:如果你想搜索安裝某個模塊或者發(fā)布一個自己的模塊可以到移步到:pypi.org/
1、time和datetime時間模塊
① 基本操作
代碼示例如下:
import?time,?datetime#?獲取當前時間
moment?=?time.localtime()
print("年:%s"?%?moment[0])
print("月:%s"?%?moment[1])
print("日:%s"?%?moment[2])
print("時:%s"?%?moment[3])
print("分:%s"?%?moment[4])
print("秒:%s"?%?(moment[5]?+?1))
print("周幾:%s"?%?(moment[6]?+?1))
print("一年第幾天:%s"?%?moment[7])
print("是否為夏令時:%s"?%?moment[8],?end="\n\n")
#?格式化時間(這里要注意strftime和strptime是不一樣的!!!)
moment1?=?time.strftime('%Y-%m-%d?%H:%M:%S')
moment2?=?time.strftime('%a?%b?%d?%H:%M:%S?%Y',?time.localtime())
moment3?=?time.mktime(time.strptime(moment2,?'%a?%b?%d?%H:%M:%S?%Y'))
print(moment1)
print(moment2)
print(moment3,?end="\n\n")
#?獲得當前時間戳
print(time.time())??#?秒級
print(int(round(time.time()?*?1000)),?end="\n\n")??#?毫秒級
#?獲得當前時間(時間數(shù)組,還需strftime格式化下)
print(datetime.datetime.now(),?end="\n\n")
#?時間戳轉(zhuǎn)換為時間
#?方法一:
moment4?=?1512184082
moment5?=?time.localtime(moment4)??#?轉(zhuǎn)換成時間數(shù)組
print(time.strftime('%Y-%m-%d?%H:%M:%S',?moment5),?end="\n\n")??#?格式化
#?方法二:
moment6?=?datetime.datetime.utcfromtimestamp(moment4)
print(moment6)
moment7?=?moment6.strftime('%a?%b?%d?%H:%M:%S?%Y')
print(moment7,?end="\n\n")
#?代碼延遲執(zhí)行
time.sleep(5)
復(fù)制代碼
運行結(jié)果如下:
年:2019月:3
日:14
時:11
分:41
秒:57
周幾:4
一年第幾天:73
是否為夏令時:0
2019-03-14?11:41:56
Thu?Mar?14?11:41:56?2019
1552534916.0
1552534916.3338902
1552534916334
2019-03-14?11:41:56.333890
2017-12-02?11:08:02
2017-12-02?03:08:02
Sat?Dec?02?03:08:02?2017
復(fù)制代碼
② struct_time,字符串,時間戳之間的轉(zhuǎn)換關(guān)系
③ Python中的時間日期格式化符號
如下表所示,參考時間為(20190314 13:53:41)
| %y | 兩位數(shù)的年份表示(00-99) | 19 |
| %Y | 四位數(shù)的年份表示(000-9999) | 2019 |
| %m | 月份(01-12) | 03 |
| %d | 月內(nèi)中的一天(0-31) | 14 |
| %H | 24小時制小時數(shù)(0-23) | 13 |
| %I | 12小時制小時數(shù)(01-12) | 01 |
| %M | 分鐘數(shù)(00=59) | 53 |
| %S | 秒(00-59) | 41 |
| %a | 星期幾的英文簡寫 | Thu |
| %A | 星期幾的英文 | Thursday |
| %b | 月份的英文簡寫 | Mar |
| %B | 月份的英文 | March |
| %x | 日期 | 03/14/19 |
| %X | 時間 | 13:59:04 |
| %c | 日期和時間 | Thu Mar 14 13:54:56 2019 |
| %j | 一年中第幾天 | 073 |
| %p | 以AM和PM的方式顯示上午還是下午 | PM |
| %U | 一年中的第幾周,周天為一周的第一天 | 10 |
| %W | 一年中的第幾周,周一為一周的第一天 | 10 |
| %w | 一周中的第幾天,周天為0,周一為1 | 4 |
| %z,%Z | 當前時區(qū)的名稱 | |
| %% | %號自身 | % |
④ 一些實用的代碼片段
下面提供一些很實用的代碼片段,用到的時候復(fù)制粘貼即可:
import?datetimeimport?time
now?=?datetime.datetime.now()
#?獲得當前時間的前/后幾天,幾小時,幾秒,毫秒
#?如果是想獲得時間戳可以直接調(diào)用int(time.mktime(求出來的時間.timetuple()))
def?fetch_before_time(time_type,?value,?strf="%Y-%m-%d?%H:%M:%S"):
????if?time_type?==?'days':
????????if?value?>?0:
????????????return?(datetime.datetime.now()?+?datetime.timedelta(days=value)).strftime(strf)
????????else:
????????????return?(datetime.datetime.now()?-?datetime.timedelta(days=value)).strftime(strf)
????elif?time_type?==?'hours':
????????if?value?>?0:
????????????return?(datetime.datetime.now()?+?datetime.timedelta(hours=value)).strftime(strf)
????????else:
????????????return?(datetime.datetime.now()?-?datetime.timedelta(hours=value)).strftime(strf)
????elif?time_type?==?'seconds':
????????if?value?>?0:
????????????return?(datetime.datetime.now()?+?datetime.timedelta(seconds=value)).strftime(strf)
????????else:
????????????return?(datetime.datetime.now()?-?datetime.timedelta(seconds=value)).strftime(strf)
????elif?time_type?==?'microseconds':
????????if?value?>?0:
????????????return?(datetime.datetime.now()?+?datetime.timedelta(microseconds=value)).strftime(strf)
????????else:
????????????return?(datetime.datetime.now()?-?datetime.timedelta(microseconds=value)).strftime(strf)
#?獲得第二天凌晨的時間戳
def?fetch_morning_timestamp():
????return?int(time.time())?+?(144000?-?(int(time.time()))?%?86400)
#?構(gòu)造一個由起始事件到結(jié)束時間間所有的日期列表
def?init_date_list(begin_date,?end_date):
????date_list?=?[]
????begin_date?=?datetime.datetime.strptime(str(begin_date),?"%Y%m%d")
????end_date?=?datetime.datetime.strptime(str(end_date),?"%Y%m%d")
????while?begin_date?<=?end_date:
????????date_str?=?begin_date.strftime("%Y%m%d")
????????date_list.append(date_str)
????????begin_date?+=?datetime.timedelta(days=1)
????return?date_list
if?__name__?==?'__main__':
????print("當前時間:",?datetime.datetime.now().strftime("%Y-%m-%d?%H:%M:%S"))
????print(fetch_before_time('days',?3))
????print(fetch_before_time('hours',?-3))
????print(fetch_before_time('seconds',?3))
????print("第二天早上的時間戳:",?fetch_morning_timestamp())
????print("從20190101到20190301的日期列表:%s"?%?init_date_list(20190101,?20190301))
復(fù)制代碼
運行結(jié)果如下:
當前時間:?2019-03-14?15:44:582019-03-17?15:44:58
2019-03-14?18:44:58
2019-03-14?15:45:01
第二天早上的時間戳:?1552665600
從20190101到20190301的日期列表:['20190101',?'20190102',...過長省略...?'20190226',?'20190227',?'20190228',?'20190301']
復(fù)制代碼
2、logging日志模塊
大部分的程序都會有「記錄運行日志的需求」,而日志信息一般有這樣幾類:正常的程序運行日志,調(diào)試,錯誤或警告信息的輸出等。而日常開發(fā)中我們需要把日志持久化到本地,進行一些觀察和統(tǒng)計,錯誤排查等,如果只用print函數(shù)輸出的話,顯然有點捉襟見寸。在Python內(nèi)置了一個日志模塊:logging,它提供了標準的日志接口,支持日志分級和存儲。
① 日志分級
在開始正式學(xué)習(xí)logging前,我們先了解下「日志分級」,即:什么時候用什么等級的日志。如下表所示:
| DEBUG | 詳細的信息,常用于問題診斷 |
| INFO | 記錄關(guān)鍵節(jié)點信息,用于確認程序是否按照預(yù)期運行 |
| WARNING | 程序還是正常運行,但某些不期望的事情發(fā)生時記錄的信息(如磁盤可用空間較低) |
| ERROR | 由于更嚴重的問題導(dǎo)致某些功能不能正常運行時記錄的信息 |
| CRITICAL | 發(fā)生嚴重錯誤,導(dǎo)致程序不能繼續(xù)運行時記錄的信息 |
打印各種級別的代碼示例如下:
import?loggingif?__name__?==?'__main__':
????#?獲得一個Logger
????logger?=?logging.getLogger("Test")
????#?logging提供的簡單的配置方法,自行配置的話需要手動添加handler
????logging.basicConfig()
????#?設(shè)置輸出的log級別(大于或等于此級別的才會輸出),默認級別Warning
????logger.setLevel(logging.INFO)
????logger.debug("===?Debug?級別的信息?===")?#?不會輸出
????logger.info("===?Info?級別的信息?===")
????logger.warning("===?Warning?級別的信息?===")
????logger.error("===?Error?級別的信息?===")
????logger.critical("===?Critical?級別的信息?===")
復(fù)制代碼
運行結(jié)果如下:
INFO:Test:===?Info?級別的信息?===WARNING:Test:===?Warning?級別的信息?===
ERROR:Test:===?Error?級別的信息?===
CRITICAL:Test:===?Critical?級別的信息?===
復(fù)制代碼
② 將日志寫入到文件
日志默認是輸出到Console(屏幕)上,如果我們想把詳細的日志輸出到log文件里,則需要用到handler了,理論上可以把日志輸出到各種流中,stderr、文件、socket等都可以,在logging中已經(jīng)將各種流handler封裝好了,你也可以繼承StreamHandler類自己做一些定制,簡單的把日志寫入到文件中的代碼示例如下:
import?loggingif?__name__?==?'__main__':
????logger?=?logging.getLogger("Test")
????logger.setLevel(logging.INFO)
????#?輸出到控制臺
????logger.addHandler(logging.StreamHandler())
????#?輸出到文件
????logger.addHandler(logging.FileHandler('test.log',?encoding='UTF-8'))
????logger.debug("===?Debug?級別的信息?===")
????logger.info("===?Info?級別的信息?===")
????logger.warning("===?Warning?級別的信息?===")
????logger.error("===?Error?級別的信息?===")
????logger.critical("===?Critical?級別的信息?===")
復(fù)制代碼
運行結(jié)果如下(同時在目錄下生成了一個test.log的文件):
===?Info?級別的信息?======?Warning?級別的信息?===
===?Error?級別的信息?===
===?Critical?級別的信息?===
復(fù)制代碼
嗯,你可能有這樣的需求,Console打印Warning以上的日志,而log文件保存Debug級別以上的日志,那么可以修改下上面的代碼,修改后的代碼如下:
if?__name__?==?'__main__':????logger?=?logging.getLogger("Test")
????logger.setLevel(logging.INFO)
????#?輸出到控制臺
????s_handler?=?logging.StreamHandler()
????s_handler.setLevel(logging.WARNING)
????logger.addHandler(s_handler)
????#?輸出到文件
????f_handler?=?logging.FileHandler('test.log',?encoding='UTF-8')
????f_handler.setLevel(logging.DEBUG)
????logger.addHandler(f_handler)
????logger.debug("===?Debug?級別的信息?===")
????logger.info("===?Info?級別的信息?===")
????logger.warning("===?Warning?級別的信息?===")
????logger.error("===?Error?級別的信息?===")
????logger.critical("===?Critical?級別的信息?===")
復(fù)制代碼
運行結(jié)果如下:
#?控制臺輸出:===?Warning?級別的信息?===
===?Error?級別的信息?===
===?Critical?級別的信息?===
#?test.log文件:
===?Info?級別的信息?===
===?Warning?級別的信息?===
===?Error?級別的信息?===
===?Critical?級別的信息?===
復(fù)制代碼
③ 定制日志輸出格式
糾結(jié)完輸出到那里,接著就輸出日志的格式了,日志一般都是比較規(guī)范的,比如日志打印的時間,類型等,而不會像我們這樣隨意拼接一段字符串,對于日志格式的定制可以通過logging模塊的Formatter組件來定制。basicConfig()中的handler 自帶一個formatter,通過logging.basicConfig(**kwargs)函數(shù)進行定制,該函數(shù)可接收的關(guān)鍵字參數(shù)如下表所示。
| filename | 指定日志輸出目標文件的文件名,設(shè)置后信息就不會打印到控制臺 |
| filemode | 指定日志文件的打開模式,默認為'a',設(shè)置了filename這個才會生效 |
| format | 指定日志格式字符串,即指定日志輸出時所包含的字段信息以及它們的順序 |
| datefmt | 指定日期/時間格式,該選項要在format中包含時間字段%(asctime)s時才有效 |
| level | 指定日志器的日志級別 |
| stream | 指定日志輸出目標stream,不能和filename同時使用否則會引起ValueError異常 |
| style | Python 3.2新增,默認'%'指定format格式字符串的風(fēng)格,可取值為'%'、'{'和'$' |
format格式字符串的字段列表如下表所示:
| %(asctime)s | 日志發(fā)生的時間--人類可讀時間,如:2003-07-08 16:49:45,896 |
| %(created)f | 日志發(fā)生的時間--時間戳,就是當時調(diào)用time.time()函數(shù)返回的值 |
| %(relativeCreated)d | 日志發(fā)生的時間相對于logging模塊加載時間的相對毫秒數(shù) |
| %(msecs)d | 日志發(fā)生時間的毫秒部分 |
| %(levelname)s | 該日志記錄的文字形式的日志級別('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') |
| %(levelno)s | 該日志記錄的數(shù)字形式的日志級別(10, 20, 30, 40, 50) |
| %(name)s | 所使用的日志器名稱,默認是'root',因為默認使用的是 rootLogger |
| %(message)s | 日志記錄的文本內(nèi)容,通過 msg % args計算得到的 |
| %(pathname)s | 調(diào)用日志記錄函數(shù)的源碼文件的全路徑 |
| %(filename)s | pathname的文件名部分,包含文件后綴 |
| %(module)s | filename的名稱部分,不包含后綴 |
| %(lineno)d | 調(diào)用日志記錄函數(shù)的源代碼所在的行號 |
| %(funcName)s | 調(diào)用日志記錄函數(shù)的函數(shù)名 |
| %(process)d | 進程ID |
| %(processName)s | 進程名稱,Python 3.1新增 |
| %(thread)d | 線程ID |
| %(thread)s | 線程名稱 |
簡單的使用代碼示例如下:
import?loggingif?__name__?==?'__main__':
????logger?=?logging.getLogger("Test")
????logging.basicConfig(level=logging.INFO,
????????????????????????format="%(asctime)s?%(process)d:%(processName)s-?%(levelname)s?===?%(message)s",
????????????????????????datefmt="%Y-%m-%d?%H:%M:%S?%p")
????logger.debug("Debug?級別的信息")
????logger.info("Info?級別的信息")
????logger.warning("Warning?級別的信息")
????logger.error("Error?級別的信息")
????logger.critical("Critical?級別的信息")
復(fù)制代碼
運行結(jié)果如下:
2019-03-14?16:39:02?PM?8628:MainProcess-?INFO?===?Info?級別的信息2019-03-14?16:39:02?PM?8628:MainProcess-?WARNING?===?Warning?級別的信息
2019-03-14?16:39:02?PM?8628:MainProcess-?ERROR?===?Error?級別的信息
2019-03-14?16:39:02?PM?8628:MainProcess-?CRITICAL?===?Critical?級別的信息
復(fù)制代碼
另外要注意一點basicConfig沒有設(shè)置編碼的屬性,如果想把日志寫入到文件里,而日志里又有中文的話,只能通過一開始那種設(shè)置FileHandler對象的方式!除了通過basicConfig()設(shè)置日志格式,還可以自定義一個Formatter對象,然后調(diào)用setFormatter函數(shù)進行設(shè)置。使用代碼示例如下:
import?loggingif?__name__?==?'__main__':
????logger?=?logging.getLogger("Test")
????logger.setLevel(logging.INFO)
????#?自定義Formatter對象
????fmt?=?logging.Formatter("%(asctime)s?%(process)d:%(processName)s-?%(levelname)s?===?%(message)s",
????????????????????????????datefmt="%Y-%m-%d?%H:%M:%S?%p")
????#?輸出到控制臺
????s_handler?=?logging.StreamHandler()
????s_handler.setLevel(logging.WARNING)
????s_handler.setFormatter(fmt)
????logger.addHandler(s_handler)
????#?輸出到文件
????f_handler?=?logging.FileHandler('test.log',?encoding='UTF-8')
????f_handler.setLevel(logging.DEBUG)
????f_handler.setFormatter(fmt)
????logger.addHandler(f_handler)
????logger.debug("Debug?級別的信息")
????logger.info("Info?級別的信息")
????logger.warning("Warning?級別的信息")
????logger.error("Error?級別的信息")
????logger.critical("Critical?級別的信息")
復(fù)制代碼
運行結(jié)果如下:
#?控制臺輸出:2019-03-14?16:41:09?PM?11312:MainProcess-?WARNING?===?Warning?級別的信息
2019-03-14?16:41:09?PM?11312:MainProcess-?ERROR?===?Error?級別的信息
2019-03-14?16:41:09?PM?11312:MainProcess-?CRITICAL?===?Critical?級別的信息
#?test.log文件:
2019-03-14?16:41:09?PM?11312:MainProcess-?INFO?===?Info?級別的信息
2019-03-14?16:41:09?PM?11312:MainProcess-?WARNING?===?Warning?級別的信息
2019-03-14?16:41:09?PM?11312:MainProcess-?ERROR?===?Error?級別的信息
2019-03-14?16:41:09?PM?11312:MainProcess-?CRITICAL?===?Critical?級別的信息
復(fù)制代碼
logging除了Handler和Formatter兩個組件外還有,Filter和LoggerAdapter組件,不過用得
不多,有興趣的同學(xué)可以自行到官方文檔進行查閱:docs.python.org/3/library/l…
如果本文對你有所幫助,歡迎
留言,點贊,轉(zhuǎn)發(fā)
素質(zhì)三連,謝謝?~
轉(zhuǎn)載于:https://juejin.im/post/5cb93c7451882532b70e73d7
總結(jié)
以上是生活随笔為你收集整理的猪行天下之Python基础——10.1 Python常用模块(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 表面风平浪静,实则暗流涌动:如何智能发现
- 下一篇: JavaScript是如何工作的:Jav