在 Python 中使用期货时如何让列表对象附加值?
How to get a list object to append values when using futures in Python?
from concurrent import futures
class MyClass:
def __init__(self):
self.mylist = []
def test(self, i):
self.mylist.append(i)
myclass = MyClass()
print(myclass.mylist)
ilist = [1, 2, 3, 4]
for i in ilist:
myclass.test(i)
print(myclass.mylist)
myclass.mylist = []
with futures.ProcessPoolExecutor() as pool:
for null in pool.map(myclass.test, ilist):
pass
print(myclass.mylist)
输出:
[]
[1, 2, 3, 4]
[]
为什么将 def test
中的值附加到 self.mylist
中可以在常规循环中使用,但在使用 futures 时却不行?如何在使用期货时允许追加功能?
让我们稍微调整一下程序,以便池执行的函数 returns 列表,还可以打印 MyClass
对象的地址。
from concurrent import futures
class MyClass:
def __init__(self):
self.mylist = []
def test(self, i):
print(hex(id(self)), self.mylist, i)
self.mylist.append(i)
return self.mylist
if __name__ == "__main__":
myclass = MyClass()
ilist = [1, 2, 3, 4]
myclass.mylist = []
with futures.ProcessPoolExecutor() as pool:
for null in pool.map(myclass.test, ilist):
print(f'Output of process: {null}')
print(f'addr: {hex(id(myclass))} , {myclass.mylist}')
给出输出
Output of process: [1]
Output of process: [2]
Output of process: [3]
Output of process: [4]
0x1b88e358860 [] 1
0x20bffa28908 [] 3
0x259844b87f0 [] 2
0x1d7546d8898 [] 4
addr: 0x20e5ebc5400 , []
如您所见,每个进程都在处理 MyClass
对象的不同副本。
现在让我们用 ThreadPoolExecutor
替换 ProcessPoolExecutor
。
现在结果如下所示:
0x1a323eb5438 [] 1
0x1a323eb5438 [1] 2
0x1a323eb5438 [1, 2] 3
0x1a323eb5438 [1, 2, 3] 4
Output of process: [1, 2, 3, 4]
Output of process: [1, 2, 3, 4]
Output of process: [1, 2, 3, 4]
Output of process: [1, 2, 3, 4]
addr: 0x1a323eb5438 , [1, 2, 3, 4]
现在每个线程都在处理同一个对象。
简而言之,进程有自己的内存,进程之间不共享。
from concurrent import futures
class MyClass:
def __init__(self):
self.mylist = []
def test(self, i):
self.mylist.append(i)
myclass = MyClass()
print(myclass.mylist)
ilist = [1, 2, 3, 4]
for i in ilist:
myclass.test(i)
print(myclass.mylist)
myclass.mylist = []
with futures.ProcessPoolExecutor() as pool:
for null in pool.map(myclass.test, ilist):
pass
print(myclass.mylist)
输出:
[]
[1, 2, 3, 4]
[]
为什么将 def test
中的值附加到 self.mylist
中可以在常规循环中使用,但在使用 futures 时却不行?如何在使用期货时允许追加功能?
让我们稍微调整一下程序,以便池执行的函数 returns 列表,还可以打印 MyClass
对象的地址。
from concurrent import futures
class MyClass:
def __init__(self):
self.mylist = []
def test(self, i):
print(hex(id(self)), self.mylist, i)
self.mylist.append(i)
return self.mylist
if __name__ == "__main__":
myclass = MyClass()
ilist = [1, 2, 3, 4]
myclass.mylist = []
with futures.ProcessPoolExecutor() as pool:
for null in pool.map(myclass.test, ilist):
print(f'Output of process: {null}')
print(f'addr: {hex(id(myclass))} , {myclass.mylist}')
给出输出
Output of process: [1]
Output of process: [2]
Output of process: [3]
Output of process: [4]
0x1b88e358860 [] 1
0x20bffa28908 [] 3
0x259844b87f0 [] 2
0x1d7546d8898 [] 4
addr: 0x20e5ebc5400 , []
如您所见,每个进程都在处理 MyClass
对象的不同副本。
现在让我们用 ThreadPoolExecutor
替换 ProcessPoolExecutor
。
现在结果如下所示:
0x1a323eb5438 [] 1
0x1a323eb5438 [1] 2
0x1a323eb5438 [1, 2] 3
0x1a323eb5438 [1, 2, 3] 4
Output of process: [1, 2, 3, 4]
Output of process: [1, 2, 3, 4]
Output of process: [1, 2, 3, 4]
Output of process: [1, 2, 3, 4]
addr: 0x1a323eb5438 , [1, 2, 3, 4]
现在每个线程都在处理同一个对象。
简而言之,进程有自己的内存,进程之间不共享。