在上下文管理器函数中使用Python记录器



我是python的新手,在运行python 3.6时遇到了这个问题。在我的主脚本中,我试图运行一个记录器,但我无法让记录器在另一个(上下文管理器(函数中正常工作。然而,它在函数之外运行良好。

import logging
from contextlib import contextmanager
import os
# Use log for debugging
log = logging.getLogger('my_logger')
log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(message)s - %(levelname)s - %(asctime)s')
# Prevent duplicate logs
if (log.hasHandlers()):
log.handlers.clear()
fh = logging.FileHandler('csv_compiler_errors.txt')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
log.addHandler(fh)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
log.addHandler(ch)

# Create contextmanager function 
@contextmanager
def change_dir(newdir):
log = logging.getLogger('my_logger')
prevdir = os.getcwd()
try:
yield os.chdir(os.path.expanduser(newdir))
finally:
os.chdir(prevdir)
log.info("Last directory used: ", newdir)
log.info("Returned to directory: ", os.getcwd())
with change_dir(os.getcwd()):
print('test script')
log.info('the logger works outside of the function')

这是返回的相当长的错误:

--- Logging error ---
Traceback (most recent call last):
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 1081, in emit
msg = self.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 925, in format
return fmt.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 664, in format
record.message = record.getMessage()
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 369, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "C:/Python/csvcompiler/venv/test.py", line 39, in <module>
print('test script')
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32libcontextlib.py", line 120, in __exit__
next(self.gen)
File "C:/Python/csvcompiler/venv/test.py", line 35, in change_dir
log.info("Last directory used: ", newdir)
Message: 'Last directory used: '
Arguments: ('C:\Python\csvcompiler\venv',)
--- Logging error ---
Traceback (most recent call last):
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 1081, in emit
msg = self.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 925, in format
return fmt.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 664, in format
record.message = record.getMessage()
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 369, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "C:/Python/csvcompiler/venv/test.py", line 39, in <module>
print('test script')
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32libcontextlib.py", line 120, in __exit__
next(self.gen)
File "C:/Python/csvcompiler/venv/test.py", line 35, in change_dir
log.info("Last directory used: ", newdir)
Message: 'Last directory used: '
Arguments: ('C:\Python\csvcompiler\venv',)
--- Logging error ---
Traceback (most recent call last):
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 1081, in emit
msg = self.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 925, in format
return fmt.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 664, in format
record.message = record.getMessage()
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 369, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "C:/Python/csvcompiler/venv/test.py", line 39, in <module>
print('test script')
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32libcontextlib.py", line 120, in __exit__
next(self.gen)
File "C:/Python/csvcompiler/venv/test.py", line 36, in change_dir
log.info("Returned to directory: ", os.getcwd())
Message: 'Returned to directory: '
Arguments: ('C:\Python\csvcompiler\venv',)
--- Logging error ---
Traceback (most recent call last):
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 1081, in emit
msg = self.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 925, in format
return fmt.format(record)
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 664, in format
record.message = record.getMessage()
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32liblogging__init__.py", line 369, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "C:/Python/csvcompiler/venv/test.py", line 39, in <module>
print('test script')
File "C:UsersPhilipAppDataLocalProgramsPythonPython38-32libcontextlib.py", line 120, in __exit__
next(self.gen)
File "C:/Python/csvcompiler/venv/test.py", line 36, in change_dir
log.info("Returned to directory: ", os.getcwd())

你对我的情况有什么建议或指导吗?非常感谢。

失败不是因为它被放在哪里,而是因为如何调用日志记录方法。

>>> import logging
>>> logger = logging.getLogger('demo')
>>> logger.warning('the logger works outside of the function')
the logger works outside of the function
>>> logger.warning('the logger works outside of the function', 123)
--- Logging error ---
Traceback (most recent call last):
File "/usr/lib64/python3.6/logging/__init__.py", line 992, in emit
msg = self.format(record)
File "/usr/lib64/python3.6/logging/__init__.py", line 838, in format
return fmt.format(record)
File "/usr/lib64/python3.6/logging/__init__.py", line 575, in format
record.message = record.getMessage()
File "/usr/lib64/python3.6/logging/__init__.py", line 338, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "<stdin>", line 1, in <module>
Message: 'the logger works outside of the function'
Arguments: (123,)

我可以看到您正在尝试记录额外的参数——消息字符串必须包含替换这些参数的令牌。在我的示例中,我将使用%d来表示整数(%s将表示字符串替换,这是标准格式样式的一部分-请参阅日志变量数据(

>>> logger.warning('the logger works outside of the function (%d)', 123)
the logger works outside of the function (123)

对于您的用例,只需在末尾放置一个%s来表示将放置newlineos.getcwd()的位置。

log.info("Last directory used: %s", newdir)
log.info("Returned to directory: %s", os.getcwd())

最新更新