Избегайте проверки, если регистратор существует


При использовании входа в python, как это

import logging
logging.basicConfig(level=logging.INFO)
logger = None
if <some condition>:
   logger = logging.getLogger(__name__)
... some code ...
logger.debug('message')
Можно ли избежать вызова logger.debug, если он не существует без оператора if?
3 2

3 ответа:

Можно построить объект-оболочку и использовать его везде:

class LoggerWrapper(object):

    def __init__(self, logger):
        self.logger = logger

    def debug(self, *args, **kwargs):
        if self.logger is None:
            return
        self.logger.debug(*args, **kwargs)

my_wrapper = LoggerWrapper(logger)
my_wrapper.debug('message')

Как уже было сказано, это не относится к модулю ведения журнала Python. Любая переменная var, которая также может быть None, должна быть проверена перед вызовом метода для нее (var.method()).

Может быть проще всегда определять регистратор и просто отключить ведение журнала через конфигурацию / настройки ведения журнала. Это сохраняет код чистым, все вызовы регистратора будут успешными, но выходные данные никуда не денутся, если это конкретный регистратор отключен.

Наконец, вы можете выбрать действительно использовать оператор if, поскольку он не является по своей сути намного большим кодом:

if logger:
    logger.debug('message')

Это не то, как вы используете ведение журнала: он полностью упускает суть. Суть в том, чтобы всегда просто регистрировать, а затем (на уровне приложения) соответствующим образом настраивать обработчики, чтобы они либо записывали уровень отладки, либо нет. В конфигурации уровня приложения можно даже задать обработчик для регистраторов в каждом модуле. Дополнительную информацию смотрите в документации по ведению журнала Python.

Можно ли избежать вызова logger.debug, если он не существует без оператора if?

Ну, вы можете (ab)использовать выражение if, или выражение or, или различные другие вещи, но в противном случае, не совсем.

Однако вы всегда можете написать функцию-оболочку:
def logdebug(*args):
    if logger:
        logger.debug(*args)

logdebug('message')
logdebug('other message')

Вы можете делать и другие, подобные трюки. Например, вместо того, чтобы иметь logger = None, Вы можете создать объект, который имеет метод debug, который делает ничего:
class Dummy(object):
    def debug(self, *args): pass
logger = Dummy()

Или, что еще лучше, всегда создавайте регистратор и настраивайте его с обработчиком null, или-проще всего-просто установите его уровень ведения журнала выше, чем debug.


Но заметьте, что ни один из них не заменит полностью утверждение if. Рассмотрим, например:
if logger:
    logger.debug(very_expensive_function())

logdebug(very_expensive_function())

Первый вызовет только very_expensive_function, чтобы создать сообщение журнала, если оно вам действительно нужно; второй вызовет его всегда, а затем просто выбросит, если вам это не нужно. оно.