豬行天下之Python基礎——10.1 Python經常使用模塊(上)

內容簡述:

  • 一、time和datetime模塊
  • 二、logging模塊

PS:若是你想搜索安裝某個模塊或者發佈一個本身的模塊能夠到移步到:pypi.org/css


一、time和datetime時間模塊


① 基本操做

代碼示例以下html

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")  # 毫秒級

# 得到當前時間(時間數組,還需strftime格式化下)
print(datetime.datetime.now(), end="\n\n")

# 時間戳轉換爲時間
# 方法一:
moment4 = 1512184082
moment5 = time.localtime(moment4)  # 轉換成時間數組
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")

# 代碼延遲執行
time.sleep(5)
複製代碼

運行結果以下python

年: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
複製代碼

② struct_time,字符串,時間戳之間的轉換關係


③ Python中的時間日期格式化符號

以下表所示,參考時間爲(20190314 13:53:41)nginx

符號 描述 示例
%y 兩位數的年份表示(00-99) 19
%Y 四位數的年份表示(000-9999) 2019
%m 月份(01-12) 03
%d 月內中的一天(0-31) 14
%H 24小時制小時數(0-23) 13
%I 12小時制小時數(01-12) 01
%M 分鐘數(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 當前時區的名稱
%% %號自身 %

④ 一些實用的代碼片斷

下面提供一些很實用的代碼片斷,用到的時候複製粘貼便可:數組

import datetime
import time

now = datetime.datetime.now()


# 得到當前時間的前/後幾天,幾小時,幾秒,毫秒
# 若是是想得到時間戳能夠直接調用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)


# 構造一個由起始事件到結束時間間全部的日期列表
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(2019010120190301))
複製代碼

運行結果以下ruby

當前時間: 2019-03-14 15:44:58
2019-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']
複製代碼

二、logging日誌模塊

大部分的程序都會有「記錄運行日誌的需求」,而日誌信息通常有這樣幾類:正常的程序運行日誌調試錯誤或警告信息的輸出等。而平常開發中咱們須要把日誌持久化到本地,進行一些觀察和統計,錯誤排查等,若是隻用print函數輸出的話,顯然有點捉襟見寸。在Python內置了一個日誌模塊:logging,它提供了標準的日誌接口,支持日誌分級和存儲app


① 日誌分級

在開始正式學習logging前,咱們先了解下「日誌分級」,即:何時用什麼等級的日誌。以下表所示:socket

級別 建議何時使用
DEBUG 詳細的信息,經常使用於問題診斷
INFO 記錄關鍵節點信息,用於確認程序是否按照預期運行
WARNING 程序仍是正常運行,但某些不指望的事情發生時記錄的信息(如磁盤可用空間較低)
ERROR 因爲更嚴重的問題致使某些功能不能正常運行時記錄的信息
CRITICAL 發生嚴重錯誤,致使程序不能繼續運行時記錄的信息

打印各類級別的代碼示例以下:函數

import logging

if __name__ == '__main__':
    # 得到一個Logger
    logger = logging.getLogger("Test")

    # logging提供的簡單的配置方法,自行配置的話須要手動添加handler
    logging.basicConfig()

    # 設置輸出的log級別(大於或等於此級別的纔會輸出),默認級別Warning
    logger.setLevel(logging.INFO)
    logger.debug("=== Debug 級別的信息 ==="# 不會輸出
    logger.info("=== Info 級別的信息 ===")
    logger.warning("=== Warning 級別的信息 ===")
    logger.error("=== Error 級別的信息 ===")
    logger.critical("=== Critical 級別的信息 ===")
複製代碼

運行結果以下學習

INFO:Test:=== Info 級別的信息 ===
WARNING:Test:=== Warning 級別的信息 ===
ERROR:Test:=== Error 級別的信息 ===
CRITICAL:Test:=== Critical 級別的信息 ===
複製代碼

② 將日誌寫入到文件

日誌默認是輸出到Console(屏幕)上,若是咱們想把詳細的日誌輸出到log文件裏,則須要用到handler了,理論上能夠把日誌輸出到各類流中stderr文件socket等均可以,在logging中已經將各類流handler封裝好了,你也能夠繼承StreamHandler類本身作一些定製,簡單的把日誌寫入到文件中的代碼示例以下:

import logging

if __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 級別的信息 ===")
複製代碼

運行結果以下(同時在目錄下生成了一個test.log的文件):

=== Info 級別的信息 ===
=== Warning 級別的信息 ===
=== Error 級別的信息 ===
=== Critical 級別的信息 ===
複製代碼

嗯,你可能有這樣的需求,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 級別的信息 ===")
複製代碼

運行結果以下

# 控制檯輸出:
=== Warning 級別的信息 ===
=== Error 級別的信息 ===
=== Critical 級別的信息 ===

# test.log文件:
=== Info 級別的信息 ===
=== Warning 級別的信息 ===
=== Error 級別的信息 ===
=== Critical 級別的信息 ===
複製代碼

③ 定製日誌輸出格式

糾結完輸出到那裏,接着就輸出日誌的格式了,日誌通常都是比較規範的,好比日誌打印的時間類型等,而不會像咱們這樣隨意拼接一段字符串,對於日誌格式的定製能夠經過logging模塊Formatter組件來定製。basicConfig()中的handler 自帶一個formatter,經過logging.basicConfig(**kwargs)函數進行定製,該函數可接收的關鍵字參數以下表所示。

參數 描述
filename 指定日誌輸出目標文件的文件名,設置後信息就不會打印到控制檯
filemode 指定日誌文件的打開模式,默認爲'a',設置了filename這個纔會生效
format 指定日誌格式字符串,即指定日誌輸出時所包含的字段信息以及它們的順序
datefmt 指定日期/時間格式,該選項要在format中包含時間字段%(asctime)s時纔有效
level 指定日誌器的日誌級別
stream 指定日誌輸出目標stream,不能和filename同時使用不然會引發ValueError異常
style Python 3.2新增,默認'%'指定format格式字符串的風格,可取值爲'%'、'{'和'$'

format格式字符串的字段列表以下表所示:

參數 描述
%(asctime)s 日誌發生的時間--人類可讀時間,如:2003-07-08 16:49:45,896
%(created)f 日誌發生的時間--時間戳,就是當時調用time.time()函數返回的值
%(relativeCreated)d 日誌發生的時間相對於logging模塊加載時間的相對毫秒數
%(msecs)d 日誌發生時間的毫秒部分
%(levelname)s 該日誌記錄的文字形式的日誌級別('DEBUG', 'INFO', 'WARNING',
'ERROR', 'CRITICAL')
%(levelno)s 該日誌記錄的數字形式的日誌級別(10, 20, 30, 40, 50)
%(name)s 所使用的日誌器名稱,默認是'root',由於默認使用的是 rootLogger
%(message)s 日誌記錄的文本內容,經過 msg % args計算獲得的
%(pathname)s 調用日誌記錄函數的源碼文件的全路徑
%(filename)s pathname的文件名部分,包含文件後綴
%(module)s filename的名稱部分,不包含後綴
%(lineno)d 調用日誌記錄函數的源代碼所在的行號
%(funcName)s 調用日誌記錄函數的函數名
%(process)d 進程ID
%(processName)s 進程名稱,Python 3.1新增
%(thread)d 線程ID
%(thread)s 線程名稱

簡單的使用代碼示例以下

import logging

if __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 級別的信息")
複製代碼

運行結果以下

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 級別的信息
複製代碼

另外要注意一點basicConfig沒有設置編碼的屬性,若是想把日誌寫入到文件裏,而日誌裏又有中文的話,只能經過一開始那種設置FileHandler對象的方式!除了經過basicConfig()設置日誌格式,還能夠自定義一個Formatter對象,而後調用setFormatter函數進行設置。使用代碼示例以下:

import logging

if __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 級別的信息")
複製代碼

運行結果以下

# 控制檯輸出:
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 級別的信息
複製代碼

logging除了HandlerFormatter兩個組件外還有,FilterLoggerAdapter組件,不過用得
很少,有興趣的同窗能夠自行到官方文檔進行查閱:docs.python.org/3/library/l…


若是本文對你有所幫助,歡迎
留言,點贊,轉發
素質三連,謝謝😘~

相關文章
相關標籤/搜索