Python ContextManager使用块访问调用的局部变量()
我正在尝试编写一个带有上下文管理器的多线程助手。其思想是在一个块中定义一组函数,上下文管理器“神奇地”处理调度和所有事情。简化的工作版本如下所示:Python ContextManager使用块访问调用的局部变量(),python,scope,Python,Scope,我正在尝试编写一个带有上下文管理器的多线程助手。其思想是在一个块中定义一组函数,上下文管理器“神奇地”处理调度和所有事情。简化的工作版本如下所示: import contextlib @contextlib.contextmanager def multi_threaded(count): funcs = [] yield funcs my_slice = int(count / len(funcs)) for i, func in enumerate(func
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()
我读到,至少没有丑陋的黑客,但我认为我的解决方案最终并没有那么丑陋:
您在创建时将locals()
字典传递到contextmanager,contextmanager在屈服后查询该字典,以收集任何可调用项:
@contextlib.contextmanager
def多线程(阻塞局部变量,计数):
产量
funcs=[fn表示块中的fn_locals.values()如果可调用(fn)]
my_slice=int(count/len(funcs))
对于i,枚举中的func(funcs):
开始=我的切片*i
func(开始,开始+我的切片)
def spawn_many():
数据集=[1,2,3,4,5]
使用多线程(局部变量(),len(数据集)):
def foo(开始、结束):
打印(“foo”+str(数据集[start\u idx:end]))
def bar(开始\u idx,结束):
打印(“条”+str(数据集[start\u idx:end]))
#重新同步先前传递给multi_threaded()的本地指令。
本地人()
产生许多
请注意,由于最后一次调用块中的
locals()。似乎只有在调用locals()
时,Python才会同步locals()
字典函数局部变量。如果没有最后一次调用,多线程
会将{'dataset':[1,2,3,4,5]}
视为局部变量。是的,这看起来肯定要好得多。我将把这个问题留一段时间不回答,因为我仍然希望找到一种解决方案,它不需要用户可能会漏掉的代码行。您找到更好的解决方案了吗?