logging模塊的使用和json模塊
可在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參數會被忽略。View Code#格式 %(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模塊
一什麽叫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模塊