代码之家  ›  专栏  ›  技术社区  ›  msw

python库是否自然地依赖于全局命名空间?

  •  1
  • msw  · 技术社区  · 14 年前

    当我试图确定两台发电机的相对性能时,首先遇到了这个问题:

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

    所以我深入研究了timeit模块,发现setup和语句是用它们自己的私有名称空间(最初是空的名称空间)计算的,因此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> .

    我只给出了代码片段,因为只需将它们拉到模块或对象级的def中,就可以轻松地修复这些情况。这里的bug似乎在我对名称空间使用的一般语义的理解中。如果语言的本质要求我创造更多 def 我很乐意这么做;但我担心我遗漏了一个基本概念。为什么对全局名称空间有如此强烈的依赖?或者,我不明白什么?

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

    1 回复  |  直到 14 年前
        1
  •  3
  •   Alex Martelli    14 年前

    这个 pickle 在最一般的情况下,协议在选择类和函数时会遇到一个严重的问题;相反,通过“按名称”选择它们,它会使困难消失,但最终会要求它们绑定到(并且可以通过)模块中顶级的名称(因为模块是它的OWn名称空间,不与“名称空间是一个响亮的好主意”冲突,毕竟;-)。

    至于你 timeit 问题是,我不理解你所说的“全局名称空间”的意思,例如:

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

    命名空间,其中 g is bound使绑定可以通过重复的语句完全访问。如果你要做的事 G 是发电机,也许你的问题是发电机没有 .get() 方法也许你的意思是 .next() ?