簡體   English   中英

在 Python 中作為調用者模塊記錄

[英]Logging as the caller module in Python

我有以下應用程序結構:

./utils.py
def do_something(logger=None):
    if not logger:
        logger = logging.getLogger(__name__)

    print('hello')
    logger.debug('test')

./one.py
from utils import do_something
logger = logging.getLogger(__name__)
do_something(logger=logger)

./two.py
from utils import do_something
logger = logging.getLogger(__name__)
do_something(logger=logger)

現在,然后運行,日志輸出將顯示使用函數( onetwo )而不是utils的各個模塊的名稱。 然后我使用此信息(記錄器的名稱)來過濾消息。

有沒有辦法做到這一點而不必將記錄器作為參數傳遞? 我是否必須基本上內省調用者函數並基於此初始化記錄器? 當在整個代碼庫中使用一個函數但記錄器應該是調用該函數的人時,這種類型的配方的常見解決方案是什么?

變量logger是一個全局變量,可以像這樣從do_something()函數內部訪問:

logger = logging.getLogger(__name__)
def do_something():
    x = logger

仔細閱讀本文后:

當在整個代碼庫中使用一個函數但記錄器應該是調用該函數的人時,這種類型的配方的常見解決方案是什么?

簡單的英語將是:

如何從導入的函數do_something()訪問全局變量logger

我的結論是沒有其他辦法!
對於這種特殊情況,您必須將 logger 作為參數傳遞。

from utils import do_something
logger = logging.getLogger(__name__)

do_something()  # logger global is not visible in do_something()
do_something(logger=logger)  # the only way

logger作為參數傳遞對我來說很好。 但是,如果您有很多對do_something調用,那么在每個調用中傳遞相同的記錄器不僅過於冗長而且容易出錯——您可能會錯誤地傳遞錯誤的記錄器。 此外,雖然您確實需要讓do_something知道記錄器,但在您調用它的時候這樣做可能沒有意義——您想做某事,而不是弄亂記錄器。 OOP 拯救:使do_something成為類的方法並在實例化類時傳遞記錄器,然后您不需要將其傳遞給方法。

# utils.py
class UsefulObject:
    def __init__(self, logger):
        self._logger = logger

    def do_something(self):
        print('hello')
        self._logger.debug('test')

現在在客戶端模塊中,您創建了一個UsefulObject實例,您可以在其上調用.do_something ,而無需每次都傳遞記錄器。

# one.py
from utils import UsefulObject
logger = logging.getLogger(__name__)
useful_object = UsefulObject(logger)  # do this once
# ...
useful_object.do_something()  # do this many times, do not pass the logger

如果您不喜歡現有的解決方案,這里有一個神奇的方法:

def do_something():
    logger = inspect.currentframe().f_back.f_globals['log']
    ...

調用函數必須有一個名為log的全局變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM