这两种代码似乎具有相似的性能。在这种情况下范围如何工作?他们中的任何一个比另一个更好吗?是否有更好的方法来实现相同的行为?
代码 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)
最佳答案
好吧,生成的代码有不同(至少在使用 CPython 2.7.12 时):
def runThread(a):
def threadFunc():
while True:
print a
time.sleep(1)
t = threading.Thread(target=threadFunc)
t.start()
将在 threadFunc()
中为 a
发出一个 LOAD_GLOBAL
操作码(输出来自 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
为您提供了更多的灵 active ,因为即使在线程已经运行后您仍然可以修改 a
。当将 a
作为参数传递给线程函数时,这种可能性或多或少消失了。无论如何,我会认为前者是一种反模式,除非它的 a
是线程终止标志。
关于Python 线程作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38716886/