繁体   English   中英

如何使用记录器在 Python 的一行中打印一个列表

[英]How to use logger to print a list in just one line in Python

我想在 Python 3.6 中仅登录一行来打印列表。 目前我的代码看起来像这样。

logger = logging.getLogger()
logger.setLevel(log_level)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(log_level)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch.setFormatter(formatter)
logger.addHandler(ch)

# some codes in-between

num_list = [1, 2, 3, 4, 5]
logger.info("Numbers in num_list are: ")
for item in num_list:
    logger.info(item)

我想要得到的是

2018-07-23 17:29:30,200 - root - INFO - Numbers in num_list are: 1 2 3 4 5

但是,我会得到

2018-07-23 17:29:30,200 - root - INFO - Numbers in num_list are:
2018-07-23 17:29:30,200 - root - INFO - 1
2018-07-23 17:29:30,200 - root - INFO - 2
2018-07-23 17:29:30,200 - root - INFO - 3
2018-07-23 17:29:30,200 - root - INFO - 4
2018-07-23 17:29:30,200 - root - INFO - 5

我知道如果我使用print到 output,我可以使用print(item, end=" ")显式更改 output 之后的内容。 但是,日志记录似乎不接受end作为输入参数。

有谁知道如何获得所需的 output? 非常感谢!

您正在使用 for 循环遍历您的所有列表并逐一记录它: logger.info("Numbers in num_list are: {}".format(' '.join(map(str, num_list))))一次性全部发布

请参阅: https : //docs.python.org/3/library/stdtypes.html?highlight=str#str.join

不完全是你想要的,但更懒惰:当你想创建一些快速调试时它可能很有用:

num_list = [1, 2, 3, 4, 5]
logger.info(str(("Numbers in num_list are: ",num_list))

输出:

('Numbers in num_list are: ', [1, 2, 3, 4, 5])

输出流(由print )和消息日志之间存在很大差异。 流是可能碰巧包含换行符的字符序列(或二进制字符串的字节)。 当您在终端上显示这些换行符时(或打印它们时),这些换行符将被解释。

日志是一系列消息,每条消息都应该是原子的。 记录消息后,您不能向其中添加任何内容,只能记录新消息。

所以你必须首先完全构建你的消息,然后记录它:

num_list = [1, 2, 3, 4, 5]
msg = "Numbers in num_list are: " + " ".join(num_list)      # fully build the message
logger.info(msg)                                            #  and then log it

我在这里找到的另一个不错的捷径 -

nums = [3, 87, 28, 25, 96]
logging.debug("Here are my favourite numbers: " + str(nums)[1:-1])

"""
 Output:
 Here are my favorite numbers: 3, 87, 28, 25, 96
""" 

另一个使用map -

logging.debug("Favourite numbers are: ".join(map(str, nums))

您可以将格式字符串和参数传递给logging

debug()文档使用这个例子:

d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning('Protocol problem: %s', 'connection reset', extra=d)

对于您的情况,您可以将num_list作为字符串传递给格式字符串,它会为您打印出来。

>>> num_list = [1, 2, 3, 4, 5, ]
>>> logger.info("Numbers in num_list are: %s", num_list)
INFO: Numbers in num_list are: [1, 2, 3, 4, 5]

>>> num_list = [1, 2, 3, 4, 5, [44,454,54], { "aa": 234} ]
>>> logger.info("Complex example: %s", num_list)
INFO: Complex example: [1, 2, 3, 4, 5, [44, 454, 54], {'aa': 234}]

正如@Maico Timmerman 指出的那样:

最好让日志记录模块使用 %-syntax 进行实际格式化,因为消息可能根本不会被打印。

Python 日志记录的一大特点是(可能很昂贵)字符串连接仅在日志记录级别意味着要输出消息时才执行。

但是,在以下代码中,始终执行str()map()join() ,如果日志记录级别高于调试,则结果可能会被丢弃:

logging.debug("Favourite numbers are: ".join(map(str, nums))

我创建了一个小类,它允许对序列进行直观的单行记录,如下所示:

logging.debug("Favourite numbers are: %s", rstr(nums))

其中rstr类定义如下:

class rstr:
    """Wrapper to recursively str()ise a list or tuple or set. The work is only
    performed in the __str__ call so these objects 'cost' very little if they
    are never actually used (e.g. as in a logger.debug() argument when the
    message is never output."""
    
    def __init__(self, seq):
        """Creates an rstr instance which will string-ise the argument when
        called."""
        self._seq = seq
    
    def __str__(self):
        """String-ise and return the argument passed to the constructor."""
        if isinstance(self._seq, list):
            return "[" + self._str_items() + "]"
        elif isinstance(self._seq, tuple):
            return "(" + self._str_items() + ")"
        elif isinstance(self._seq, set):
            return "{" + self._str_items() + "}"
        else:
            return str(self._seq)
    
    def _str_items(self):
        """Returns the string-ised forms of the items in the argument passed to
        the constructor - no start/end brackets/braces."""
        return ", ".join(map(str, self._seq))
    

如果需要,这显然可以完全递归,但为了清楚起见,这里显示了更简单的版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM