在尝试确定两个生成器的相对性能时,我首先遇到了这个问题:

t = timeit.repeat('g.get()', setup='g = my_generator()')


因此,我进入timeit模块,发现setup和statement是使用它们自己的私有,最初为空的命名空间进行评估的,因此g.get()语句自然无法访问g的绑定。显而易见的解决方案是将它们包装到一个类中,从而添加到全局名称空间中。

在另一个项目中,尝试使用多处理模块在工作人员之间分配任务时,我再次碰到了这一点。我什至把所有东西都很好地捆绑在一起,但是不幸的是电话

pool.apply_async(runmc, arg)


失败并出现PicklingError,因为埋在runmc实例化的工作对象内部是(有效)赋值:

self.predicate = lambda x, y: x > y


因此无法(可以理解)对整个对象进行腌制,而:

def foo(x, y):
    return x > y
pickle.dumps(foo)


很好,顺序

bar = lambda x, y: x > y


callable(bar)type(bar)生成True,但从Can't pickle <function <lambda> at 0xb759b764>: it's not found as __main__.<lambda>生成True。

我只给出了代码片段,因为我只需将它们拉入模块或对象级别的defs就可以轻松修复这些情况。此处的错误似乎出在我对名称空间使用语义的一般理解中。如果语言的性质要求我创建更多的def语句,我会很乐意这样做;我担心我会错过一个基本概念。为什么如此强烈地依赖全局名称空间?或者,我无法理解什么?

Namespaces are one honking great idea -- let's do more of those!

最佳答案

在大多数情况下,pickle协议在选择类和功能时都会遇到严重的问题;而是通过“按名称”腌制它们,这使困难消失了,但是发现要求它们必须与模块中顶级名称(并且由于模块是其自身的名称空间,毕竟与“命名空间是一个很棒的主意”不冲突;-)。

至于您的timeit问题,我不会理解您所说的“全局名称空间”的含义-例如:

>>> timeit.repeat('g.get(23)', 'g = {}')
[0.29134988784790039, 0.27160286903381348, 0.27237796783447266]


绑定g的名称空间使绑定可以被重复的语句完全访问。如果您绑定到g的是生成器,则可能是您的问题是生成器没有.get()方法,也许您是说.next()

关于python - Python库是否自然依赖于全局 namespace ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2534847/

10-15 15:55