当有多个生成器调用公共记录器时如何修复 python 记录顺序

How to fix the python logging order when there are multiple generators calling a common logger

有一个生成器列表 gen_list = [gen_1, gen_2, gen_3].

每个 gen_x 都有一个日志语句,将日志行放在一个公共日志文件中。

例如,

gen_1 放置日志行“log 1”

gen_2 放置日志行“log 2”

gen_3 放置日志行“log 3”

执行gen_list后,log_file如下所示。

日志 1

日志 2

日志 3

日志 3

日志 2

日志 1

日志 1

日志 2

日志 3

...

列表中生成器的执行顺序是交替的。 (1, 2, 3, 3, 2, 1, 1, 2, 3, ...)

有没有什么办法可以让命令总是向前的? (1, 2, 3, 1, 2, 3, 1, 2, 3, ...)

例如,我希望log_file是

日志 1

日志 2

日志 3

日志 1

日志 2

日志 3

...

您可以使用 zip() 来模拟遍历迭代器的循环,然后使用 itertools 中的 chain.from_iterable()zip() 中的元组链接在一起。这允许您一次从一个生成器中读出一个元素。这种方法的一个显着优点是您可以使用任意多个生成器。

这是一个例子:

from itertools import chain

def gen_1():
    for i in range(10):
        yield "log1"

def gen_2():
    for i in range(10):
        yield "log2"

def gen_3():
    for i in range(10):
        yield "log3"

gen_list = [gen_1, gen_2, gen_3]

for elem in chain.from_iterable(zip(*[gen() for gen in gen_list])):
    print(elem)

使用 zip() 后,您将生成如下内容:

[("log1", "log2", "log3"), ("log1", "log2", "log3"), ...]

然后,使用 chain.from_iterable() 展平这些元组,得到如下序列:

"log1", "log2", "log3", "log1", "log2", "log3", ...

我不确定您是否提供了所有信息来解释您的问题。这个脚本:

import logging

def gen_1():
    for i in range(10):
        logging.debug('log 1: %d' % i)
        yield "log1"

def gen_2():
    for i in range(10):
        logging.debug('log 2: %d' % i)
        yield "log2"

def gen_3():
    for i in range(10):
        logging.debug('log 3: %d' % i)
        yield "log3"

gen_list = [gen_1(), gen_2(), gen_3()]

logging.basicConfig(level=logging.DEBUG, format='%(message)s')

def main():
    for i in range(10):
        v = [next(gen_list[i]) for i in range(3)]

if __name__ == '__main__':
    main()

打印,当运行(Python 3),

log 1: 0
log 2: 0
log 3: 0
log 1: 1
log 2: 1
log 3: 1
log 1: 2
log 2: 2
log 3: 2
log 1: 3
log 2: 3
log 3: 3
log 1: 4
log 2: 4
log 3: 4
log 1: 5
log 2: 5
log 3: 5
log 1: 6
log 2: 6
log 3: 6
log 1: 7
log 2: 7
log 3: 7
log 1: 8
log 2: 8
log 3: 8
log 1: 9
log 2: 9
log 3: 9