2010-03-28 66 views
1

试图确定两个发电机的相对表现,当我第一次碰见这样的:Python库对全局命名空间有自然依赖吗?

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

所以我挖成timeit模块,发现设置和声明都拥有自己的私人,最初是空的命名空间,以便评估g的绑定自然不会被g.get()语句访问。显而易见的解决方案是将它们包装到一个类中,从而添加到全局名称空间。

在另一个项目中尝试使用多处理模块在工作人员之间分配任务时,我再次遇到了这个问题。我甚至把每样东西很好地为一类,但不幸的是,呼叫

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)产生真,但它是Can't pickle <function <lambda> at 0xb759b764>: it's not found as __main__.<lambda>

我只给出了代码片段,因为我可以通过仅将它们拉出到模块或对象级别defs中来轻松修复这些情况。这里的错误似乎是我对通常命名空间使用的语义的理解。如果语言的性质要求我创建更多的def陈述,我会很乐意这样做;我担心我错过了一个重要的概念。为什么如此强烈地依赖全球命名空间?或者,我不明白的是什么?

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

回答

3

pickle协议(一个或多个)将具有一个严重的问题采摘的类和函数在最一般的情况下;通过“按名称”来代替它们,它会使难题消失,但要求它们被绑定到(并且可以恢复)模块中最高级别的名称(由于模块是它自己的名称空间,不会与“命名空间是一个好的想法”相冲突,毕竟;-)。

至于你timeit的问题,我不已了解了你的意思WRT“全局命名空间” - 例如:

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

其中g绑定的命名空间离开具有约束力的声明是完全无障碍重复。如果你对g的约束是一个发电机,也许你的问题是发电机没有.get()方法,也许你的意思是.next()

+0

谢谢,它确实是我没有考虑的模块命名空间。从C背景中,在文件范围声明的符号具有外部存储类;这与Python模块是无关的。是的,我的意思是'.next()',但我的打字手指认为他们知道的更好。 – msw 2010-03-29 10:40:03