我正在尝试使用上下文管理器编写一个多线程帮助程序。这个想法是在一个块内定义一堆函数,上下文管理器“神奇地”负责调度和所有工作。简化的工作版本如下所示:

import contextlib

@contextlib.contextmanager
def multi_threaded(count):
    funcs = []
    yield funcs
    my_slice = int(count / len(funcs))
    for i, func in enumerate(funcs):
        start = my_slice * i
        func(start, start + my_slice)


def spawn_many():
    dataset = [1, 2, 3, 4, 5]
    with multi_threaded(len(dataset)) as mt:
        def foo(start_idx, end):
            print("foo" + str(dataset[start_idx : end]))
        def bar(start_idx, end):
            print("bar" + str(dataset[start_idx : end]))
        mt.append(foo)
        mt.append(bar)

spawn_many()


这个例子有效,但是我想摆脱这些行:

        mt.append(foo)
        mt.append(bar)


这样,用户只需要定义功能,而无需将其添加到集合中。为什么?因为它不那么容易出错,所以我无法控制使用该库编写的代码。

问题是,在屈服之后,我不在def foo发生的作用域之内,因此我不知道该作用域中存在的locals(),这基本上是我需要知道在其中定义了哪些函数的知识。有什么想法/技巧/鼓励的话吗?

谢谢阅读!

最佳答案

装饰器可能会更好一些:

import contextlib

@contextlib.contextmanager
def multi_threaded(count):
    funcs = []
    yield funcs
    my_slice = int(count / len(funcs))
    for i, func in enumerate(funcs):
        start = my_slice * i
        func(start, start + my_slice)

def add_to_flist(mt):
    def _add_to_flist(func):
        mt.append(func)
        return func
    return _add_to_flist

def spawn_many():
    dataset = [1, 2, 3, 4, 5]
    with multi_threaded(len(dataset)) as mt:
        @add_to_flist(mt)
        def foo(start_idx, end):
            print("foo" + str(dataset[start_idx : end]))
        @add_to_flist(mt)
        def bar(start_idx, end):
            print("bar" + str(dataset[start_idx : end]))

spawn_many()

08-20 01:04