2016-08-02 66 views
3

这两个代码似乎都有类似的性能。范围在这种情况下如何工作?他们中的任何一个都比另一个好吗?有没有更好的方法来实现相同的行为?Python线程范围

代码1:

class ex: 
    b = 6 
    def foo(self, a): 
    def fooHandler(a): 
     while True: 
     print a 
     time.sleep(1) 
    threading.Thread(target=fooHandler, args=(a,)).start() 
x = ex() 
x.foo(10) 
x.foo(100) 
x.foo(1000) 

代码2:

class ex: 
    b = 6 
    def foo(self, a): 
    def fooHandler(): 
     while True: 
     print a 
     time.sleep(1) 
    threading.Thread(target=fooHandler).start() 
x = ex() 
x.foo(10) 
x.foo(100) 
x.foo(1000) 
+0

从我的编辑器复制时,缩进被搞砸了,它应该现在工作 – user3019917

+0

您可能想要阅读下面的内容:http://stackoverflow.com/questions/4020419/why-arent-python-nested-functions-叫关闭 – dmitri

+0

@dmitri链接是有帮助的:)谢谢 – user3019917

回答

1

那么,有在生成的代码的差值(使用CPython的2.7.12时至少):

def runThread(a): 
    def threadFunc(): 
     while True: 
      print a 
      time.sleep(1) 

    t = threading.Thread(target=threadFunc) 
    t.start() 

会发出内部threadFunc()一个LOAD_GLOBAL操作码a(输出距离inspect.dis.dis()):

8   9 LOAD_GLOBAL    1 (a) 

def runThread(a): 
    def threadFunc(a): 
     while True: 
      time.sleep(1) 

    t = threading.Thread(target=threadFunc, args=(a,)) 
    t.start() 

会发出LOAD_FAST操作码:

8   9 LOAD_FAST    0 (a) 

LOAD_FAST发生,因为编译器知道a是参数,从而查找只需要发生WRT。到当前的命名空间。 LOAD_FAST(因此名称)可能比LOAD_GLOBAL更快,但如果您需要考虑性能方面的差异,您可能不应该首先使用Python。

是的,一切都尖叫“实施细节”给我。

范围从外部范围导入a为您提供了更大的灵活性,因为即使线程已经运行,您仍然可以修改a。当将a作为参数传递给线程函数时,该可能性或多或少地消失了。无论如何,我会认为前者是反模式,除非它的a是线程终止标志。

0

这有什么好做的线程,它只是一个利用嵌套的范围值与明确地把它当作一个的事参数并从本地范围使用它。

在这种情况下使用哪种方法并不重要;无论哪种情况,您都使用相同的值。在嵌套的作用域中查找会更加昂贵,但这只是微不足道的(它本质上等同于单个dict查找,其中本地作用域查找更接近于数组访问性能)。

如果您在函数期间需要更改a的绑定,则不能使用隐式嵌套作用域访问(您必须使用不同的名称),因为您无法读写嵌套作用域Python 2中的范围变量(缺少关键字nonlocal)。使用不同的名称(最初设置为a)与在任何情况下将其作为参数相似,所以再次没有重大区别。