1. 程式人生 > >logging模塊的使用和json模塊

logging模塊的使用和json模塊

創建 表達 sage 寫入 OS dna tde mage alt

技術分享圖片
可在logging.basicConfig()函數中通過具體參數來更改logging模塊默認行為,可用參數有
filename:用指定的文件名創建FiledHandler(後邊會具體講解handler的概念),這樣日誌會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。
format:指定handler使用的日誌顯示格式。 
datefmt:指定日期時間格式。 
level:設置rootlogger(後邊會講解具體概念)的日誌級別 
stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件,默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。



#格式 %(name)s:Logger的名字,並非用戶名,詳細查看 %(levelno)s:數字形式的日誌級別 %(levelname)s:文本形式的日誌級別 %(pathname)s:調用日誌輸出函數的模塊的完整路徑名,可能沒有 %(filename)s:調用日誌輸出函數的模塊的文件名 %(module)s:調用日誌輸出函數的模塊名 %(funcName)s:調用日誌輸出函數的函數名 %(lineno)d:調用日誌輸出函數的語句所在的代碼行 %(created)f:當前時間,用UNIX標準的表示時間的浮 點數表示 %(relativeCreated)d:輸出日誌信息時的,自Logger創建以 來的毫秒數
%(asctime)s:字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒 %(thread)d:線程ID。可能沒有 %(threadName)s:線程名。可能沒有 %(process)d:進程ID。可能沒有 %(message)s:用戶輸出的消息
View Code

logging模塊

一什麽叫logging模塊,logging具體是用來幹什麽的

1、logging模塊又叫日誌模塊

具體是用來記錄的你程序運行結果。具一個例子:我們平時用手機買東西的時候,都會收到一個賬單。這就類似於一個日誌模塊

技術分享圖片

2、日誌級別

critical=50   #
fatal=critical error=40 warning=30 #warn=waring info=20 debug=10 notset=0 #不設置

3、默認級別為warning,默認打印到終端

import logging

logging.debug(調試debug)
logging.info(消息info)
logging.warning(警告warn)
logging.error(錯誤error)
logging.critical(嚴重critical)

‘‘‘
WARNING:root:警告warn
ERROR:root:錯誤error
CRITICAL:root:嚴重critical
‘‘‘

4、為logging模塊指定全局配置,針對所有logger有效,控制打印到文件中

可在logging.basicConfig()函數中通過具體參數來更改logging模塊默認行為,可用參數有
filename:用指定的文件名創建FiledHandler(後邊會具體講解handler的概念),這樣日誌會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。
format:指定handler使用的日誌顯示格式。 
datefmt:指定日期時間格式。 
level:設置rootlogger(後邊會講解具體概念)的日誌級別 
stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件,默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。



#格式
%(name)s:Logger的名字,並非用戶名,詳細查看

%(levelno)s:數字形式的日誌級別

%(levelname)s:文本形式的日誌級別

%(pathname)s:調用日誌輸出函數的模塊的完整路徑名,可能沒有

%(filename)s:調用日誌輸出函數的模塊的文件名

%(module)s:調用日誌輸出函數的模塊名

%(funcName)s:調用日誌輸出函數的函數名

%(lineno)d:調用日誌輸出函數的語句所在的代碼行

%(created)f:當前時間,用UNIX標準的表示時間的浮 點數表示

%(relativeCreated)d:輸出日誌信息時的,自Logger創建以 來的毫秒數

%(asctime)s:字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒

%(thread)d:線程ID。可能沒有

%(threadName)s:線程名。可能沒有

%(process)d:進程ID。可能沒有

%(message)s:用戶輸出的消息

 

logging的使用

#========使用
import logging
logging.basicConfig(filename=access.log,
                    format=%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s,
                    datefmt=%Y-%m-%d %H:%M:%S %p,
                    level=10)

logging.debug(調試debug)
logging.info(消息info)
logging.warning(警告warn)
logging.error(錯誤error)
logging.critical(嚴重critical)





#========結果
access.log內容:
2017-07-28 20:32:17 PM - root - DEBUG -test:  調試debug
2017-07-28 20:32:17 PM - root - INFO -test:  消息info
2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn
2017-07-28 20:32:17 PM - root - ERROR -test:  錯誤error
2017-07-28 20:32:17 PM - root - CRITICAL -test:  嚴重critical

part2: 可以為logging模塊指定模塊級的配置,即所有logger的配置

5、logging模塊的formatter,handler,logger,filter對象

#logger:產生日誌的對象

#Filter:過濾日誌的對象

#Handler:接收日誌然後控制打印到不同的地方,FileHandler用來打印到文件中,StreamHandler用來打印到終端

#Formatter對象:可以定制不同的日誌格式對象,然後綁定給不同的Handler對象使用,以此來控制不同的Handler的日誌格式
復制代碼

復制代碼
‘‘‘
critical=50
error =40
warning =30
info = 20
debug =10
‘‘‘


import logging

#1、logger對象:負責產生日誌,然後交給Filter過濾,然後交給不同的Handler輸出
logger=logging.getLogger(__file__)

#2、Filter對象:不常用,略

#3、Handler對象:接收logger傳來的日誌,然後控制輸出
h1=logging.FileHandler(t1.log) #打印到文件
h2=logging.FileHandler(t2.log) #打印到文件
h3=logging.StreamHandler() #打印到終端

#4、Formatter對象:日誌格式
formmater1=logging.Formatter(%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s,
                    datefmt=%Y-%m-%d %H:%M:%S %p,)

formmater2=logging.Formatter(%(asctime)s :  %(message)s,
                    datefmt=%Y-%m-%d %H:%M:%S %p,)

formmater3=logging.Formatter(%(name)s %(message)s,)


#5、為Handler對象綁定格式
h1.setFormatter(formmater1)
h2.setFormatter(formmater2)
h3.setFormatter(formmater3)

#6、將Handler添加給logger並設置日誌級別
logger.addHandler(h1)
logger.addHandler(h2)
logger.addHandler(h3)
logger.setLevel(10)

#7、測試
logger.debug(debug)
logger.info(info)
logger.warning(warning)
logger.error(error)
logger.critical(critical)

6、logger與handler的級別

"""
logging配置
"""

import os
import logging.config

# 定義三種日誌輸出格式 開始

standard_format = [%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]                   [%(levelname)s][%(message)s] #其中name為getlogger指定的名字

simple_format = [%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s

id_simple_format = [%(levelname)s][%(asctime)s] %(message)s

# 定義日誌輸出格式 結束

logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目錄

logfile_name = all2.log  # log文件名

# 如果不存在定義的日誌目錄就創建一個
if not os.path.isdir(logfile_dir):
    os.mkdir(logfile_dir)

# log文件的全路徑
logfile_path = os.path.join(logfile_dir, logfile_name)

# log配置字典
LOGGING_DIC = {
    version: 1,
    disable_existing_loggers: False,
    formatters: {
        standard: {
            format: standard_format
        },
        simple: {
            format: simple_format
        },
    },
    filters: {},
    handlers: {
        #打印到終端的日誌
        console: {
            level: DEBUG,
            class: logging.StreamHandler,  # 打印到屏幕
            formatter: simple
        },
        #打印到文件的日誌,收集info及以上的日誌
        default: {
            level: DEBUG,
            class: logging.handlers.RotatingFileHandler,  # 保存到文件
            formatter: standard,
            filename: logfile_path,  # 日誌文件
            maxBytes: 1024*1024*5,  # 日誌大小 5M
            backupCount: 5,
            encoding: utf-8,  # 日誌文件的編碼,再也不用擔心中文log亂碼了
        },
    },
    loggers: {
        #logging.getLogger(__name__)拿到的logger配置
        ‘‘: {
            handlers: [default, console],  # 這裏把上面定義的兩個handler都加上,即log數據既寫入文件又打印到屏幕
            level: DEBUG,
            propagate: True,  # 向上(更高level的logger)傳遞
        },
    },
}


def load_my_logging_cfg():
    logging.config.dictConfig(LOGGING_DIC)  # 導入上面定義的logging配置
    logger = logging.getLogger(__name__)  # 生成一個log實例
    logger.info(It works!)  # 記錄該文件的運行狀態

if __name__ == __main__:
    load_my_logging_cfg()

logging配置文件

json&pickle模塊:

1、什麽是json模塊,具體用來幹什麽

在了解json模塊之前,我們學習了用eval內置方法可以將一個字符串轉成python對象,不過,eval方法是

有局限性的,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就不用管了,所以eval的重點還是通常用來執行一個字符串表達式,並返回表達式的值。

import json
 x="[null,true,false,1]"
 print(eval(x)) #報錯,無法解析null類型,而json就可以
 print(json.loads(x)) 

什麽是序列化?

我們把對象(變量)從內存中變成可存儲或者傳輸的過程稱之為序列化,在python中叫picking,在其他

語言中也被稱之為serialization,marshalling,flattening等等,都是一個意思。

為什麽要序列化?

1:持久保存狀態

需知一個軟件/程序的執行就在處理一系列狀態的變化,在編程語言中,‘狀態‘會以各種各樣有結構的數據類型(也可簡單的理解為變量)的形式被保存在內存中。

內存是無法永久保存數據的,當程序運行了一段時間,我們斷電或者重啟程序,內存中關於這個程序的之前一段時間的數據(有結構)都被清空了。

在斷電或重啟程序之前將程序當前內存中所有的數據都保存下來(保存到文件中),以便於下次程序執行能夠從文件中載入之前的數據,然後繼續執行,這就是序列化。

具體的來說,你玩使命召喚闖到了第13關,你保存遊戲狀態,關機走人,下次再玩,還能從上次的位置開始繼續闖關。或如,虛擬機狀態的掛起等。

2:跨平臺數據交互

序列化之後,不僅可以把序列化後的內容寫入磁盤,還可以通過網絡傳輸到別的機器上,如果收發的雙方約定好實用一種序列化的格式,那麽便打破了平臺/語言差異化帶來的限制,實現了跨平臺數據交互。

反過來,把變量內容從序列化的對象重新讀到內存裏稱之為反序列化,即unpickling。

如何序列化之json和pickle:

json

如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標準格式,比如XML,但更好的方法是序列化為JSON,因為JSON表示出來就是一個字符串,可以被所有語言讀取,也可以方便地存儲到磁盤或者通過網絡傳輸。JSON不僅是標準格式,並且比XML更快,而且可以直接在Web頁面中讀取,非常方便。

json表示的對象就是標準的JavasScript語言的對象,json和python內置的數據類型對應如下:

import json
 
dic={name:alvin,age:23,sex:male}
print(type(dic))#<class ‘dict‘>
 
j=json.dumps(dic)
print(type(j))#<class ‘str‘>
 
 
f=open(序列化對象,w)
f.write(j)  #-------------------等價於json.dump(dic,f)
f.close()
#-----------------------------反序列化<br>
import json
f=open(序列化對象)
data=json.loads(f.read())#  等價於data=json.load(f)
import json
#dct="{‘1‘:111}"#json 不認單引號
#dct=str({"1":111})#報錯,因為生成的數據還是單引號:{‘one‘: 1}

dct={"1":"111"}
print(json.loads(dct))

#conclusion:
#        無論數據是怎樣創建的,只要滿足json格式,就可以json.loads出來,不一定非要dumps的數據才能loads

 註意點

pickle

import pickle
 
dic={name:alvin,age:23,sex:male}
 
print(type(dic))#<class ‘dict‘>
 
j=pickle.dumps(dic)
print(type(j))#<class ‘bytes‘>
 
 
f=open(序列化對象_pickle,wb)#註意是w是寫入str,wb是寫入bytes,j是‘bytes‘
f.write(j)  #-------------------等價於pickle.dump(dic,f)
 
f.close()
#-------------------------反序列化
import pickle
f=open(序列化對象_pickle,rb)
 
data=pickle.loads(f.read())#  等價於data=pickle.load(f)
 
 
print(data[age])

logging模塊的使用和json模塊