在尝试确定两个生成器的相对性能时,我首先遇到了这个问题:
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/