python-包及日誌模組使用

我要學程式設計發表於2018-08-10

一、包

1.包就是一個保護有__init__.py檔案的資料夾,包的本質就是一種模組,即包是用來匯入使用的,包內部包含的檔案也都是用來被匯入使用的.包是為了更好組織好模組,就是一個資料夾.

注:在python2中,包下必須有一個__init__.py檔案,而python3中即便沒有也不會報錯

首次匯入包,會發生三件事

  1.以包下的__init__.py檔案為基準來產生一個名稱空間

  2.執行包下的__init__.py檔案的程式碼,將執行過程中產生的名字都丟到名稱空間中

  3.在當前執行檔案中拿到一個名字p1,該p1就是指向__init__.py名稱空間的

總結包的使用需要注意的地方:

  1.但凡是在匯入語句中帶點的,點的左邊都必須是一個包

  2.匯入包就是在匯入包下的__init__.py檔案

  3.如果使用絕對匯入,絕對匯入的起始位置都是以包的頂級目錄為起始點

  4.但是包內部模組的匯入通常應該使用相對匯入,用”.”代表當前所在的檔案(而非執行檔案),兩個點代表上一級

  強調:

    1.相對匯入只能包內部的模組之間互相匯入使用

    2. “..”上一級不能超出頂級包

二、日誌模組的使用

logging模組主要是用來記錄日誌資訊的,需要注意的三點有,控制日誌級別,控制日誌格式,控制輸出的目標為檔案

等級:

  1.logging.debug(“debug日誌”) #10

  2.logging.info(“info日誌”) #20

  3.logging.warning(“warning日誌”) #30

  4.logging.error(“error日誌”) #40

  5.logging.critical(“critical日誌”) #50

可在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.basicConfig()
#======介紹
可在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引數會被忽略。


format引數中可能用到的格式化串:
%(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使用者輸出的訊息




#========使用
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的配置

logging模組中的Formatter,Handler,Logger,Filter物件

#logger:產生日誌的物件

#Filter:過濾日誌的物件

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

#Formatter物件:可以定製不同的日誌格式物件,然後繫結給不同的Handler物件使用,以此來控制不同的Handler的日誌格式

logger是第一級過濾,然後才能到handler,我們可以給logger和handler同時設定level

import logging

# 1. logger物件: 負責生產各種級別的日誌
logger1 = logging.getLogger(`使用者交易`)  # 日誌名用來標識日誌的與什麼業務有關

# 2. filter物件: 過濾日誌

# 3. handler物件: 控制日誌輸出目標位置
fh1 = logging.FileHandler(`a1.log`,encoding=`utf-8`)
fh2 = logging.FileHandler(`a2.log`,encoding=`utf-8`)
ch = logging.StreamHandler()

# 4. formmater物件
formatter1 = logging.Formatter(
    fmt=`%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s`,
    datefmt=`%Y-%m-%d %H:%M:%S %p`
)

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

# 5. 繫結logger物件與handler物件
logger1.addHandler(fh1)
logger1.addHandler(fh2)
logger1.addHandler(ch)

# 6. 繫結handler物件與formatter物件

fh1.setFormatter(formatter1)
fh2.setFormatter(formatter1)
ch.setFormatter(formatter2)

# 7. 設定日誌級別,有logger物件與handler物件兩層關卡,必須都放行最終日誌才會放行,通常二者級別相同
logger1.setLevel(10)
fh1.setLevel(10)
fh2.setLevel(10)
ch.setLevel(10)

# 8. 使用logger物件產生日誌
logger1.info(`alex給egon轉賬1個億`)

應用:

settings.py

standard_format = `%(asctime)s - task:%(name)s - %(filename)s:%(lineno)d -` 
                  ` %(levelname)s : [%(message)s]`

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

fh1_path = r`a1.log`
fh2_path = r`a2.log`

# log配置字典
LOGGING_DIC = {
    `version`: 1,
    `disable_existing_loggers`: False,
    `formatters`: {
        `standard`: {
            `format`: standard_format
        },
        `simple`: {
            `format`: simple_format
        },
    },
    `filters`: {},
    `handlers`: {
        #列印到終端的日誌
        `ch`: {
            `level`: `DEBUG`,
            `class`: `logging.StreamHandler`,  # 列印到終端
            `formatter`: `simple`
        },
        #列印到a1.log檔案的日誌
        `fh1`: {
            `level`: `DEBUG`,
            `class`: `logging.FileHandler`,  # 儲存到檔案
            `formatter`: `standard`,
            `filename`: fh1_path,  # 日誌檔案的路徑
            `encoding`: `utf-8`,  # 日誌檔案的編碼,再也不用擔心中文log亂碼了
        },
        # 列印到a2.log檔案的日誌
        `fh2`: {
            `level`: `DEBUG`,
            `class`: `logging.FileHandler`,  # 儲存到檔案
            `formatter`: `simple`,
            `filename`: fh2_path,  # 日誌檔案的路徑
            `encoding`: `utf-8`,  # 日誌檔案的編碼,再也不用擔心中文log亂碼了
        },

    },
    `loggers`: {
        ``: {
            `handlers`: [`fh1`, `fh2`, `ch`],
            `level`: `DEBUG`,
        },
    },
}

run.py

import logging.config
import settings

logging.config.dictConfig(settings.LOGGING_DIC)

logger1=logging.getLogger(`使用者交易`)
#logger1-> fh1,fh2,ch
logger1.info(`alex給egon轉賬1個億`)

logger2=logging.getLogger(`使用者許可權`)
#logger2-> fh1,fh2,ch
logger2.error(`egon沒有執行許可權`)

 

焚膏油以繼晷,恆兀兀以窮年。


相關文章