Python 3.5 全局变量不会追加
Python 3.5 global variable won't append
我正在尝试使用可以在 thread/process 完成任务时附加的全局列表。我的主线程可以从中读取但按功能无法附加它。基本上我正在请求获取工作代理,然后尝试将它们保存到列表中,然后在最后打印出列表。我已经尽量删掉了。
goodProxyList = ["test"]
def testProxy(x):
global goodProxyList
try:
test = requests.get('http://someurl.com/', proxies=proxies, timeout=10)
if test.status_code == 200:
goodProxyList.append(x)
else:
print("Something went wrong! :/" + " From PID: " + str(pid))
except:
print("SOMETHING WENT VERY WRONG" + " From PID: " + str(pid))
if __name__ == '__main__':
##Setup Stuff happens
p=Pool(2)
p.map(testProxy, proxyList)
for i in goodProxyList:
print(i)
即使我将 goodProxyList.append(x) 更改为 goodProxyList.append("Anything"),最后两行仍然输出 "test"。我做错了什么?
编辑:
我在 brianpck 的帮助下找到了答案。正如他所说,进程的工作方式似乎与线程不同。我更改为池线程,它现在可以正常工作了。
#p=Pool(2)
#p.map(testProxy, proxyList)
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.map(testProxy, proxyList)
这里的问题是 Pool
,而不是 global
。
在函数范围内追加到列表(可变对象)时,该列表也会在全局范围内发生变化。 (实际上,您甚至不必使用 global
关键字:如果函数在其自身作用域中找不到变量,它会自动在全局作用域中查找。)注意一个小 "gotcha" 在下面的代码中,因为 map
是一个类似生成器的对象:
x = []
def add_to_x(i):
x.append(i)
if __name__ == '__main__':
y = map(add_to_x, [1, 2])
print(x) # still []
list(y)
print(x) # now [1, 2]
以下带有 Pool
的简单示例虽然不起作用:
from multiprocessing import Pool
x = []
def add_to_x(i):
x.append(i)
if __name__ == '__main__':
p = Pool(2)
list(p.map(add_to_x, [1, 2]))
print(x) # prints [] !
为什么? Python multiprocessing global variable updates not returned to parent 的答案具有启发性:这里是相关部分:
When you use multiprocessing
to open a second process, an entirely new instance of Python, with its own global state, is created. That global state is not shared, so changes made by child processes to global variables will be invisible to the parent process.
您可以通过多种方式解决这个问题。一种方法是将 testProxy
更改为 is_good_proxy
,这将 return 一个布尔值。然后您可以在主循环中应用附加逻辑。
我正在尝试使用可以在 thread/process 完成任务时附加的全局列表。我的主线程可以从中读取但按功能无法附加它。基本上我正在请求获取工作代理,然后尝试将它们保存到列表中,然后在最后打印出列表。我已经尽量删掉了。
goodProxyList = ["test"]
def testProxy(x):
global goodProxyList
try:
test = requests.get('http://someurl.com/', proxies=proxies, timeout=10)
if test.status_code == 200:
goodProxyList.append(x)
else:
print("Something went wrong! :/" + " From PID: " + str(pid))
except:
print("SOMETHING WENT VERY WRONG" + " From PID: " + str(pid))
if __name__ == '__main__':
##Setup Stuff happens
p=Pool(2)
p.map(testProxy, proxyList)
for i in goodProxyList:
print(i)
即使我将 goodProxyList.append(x) 更改为 goodProxyList.append("Anything"),最后两行仍然输出 "test"。我做错了什么?
编辑:
我在 brianpck 的帮助下找到了答案。正如他所说,进程的工作方式似乎与线程不同。我更改为池线程,它现在可以正常工作了。
#p=Pool(2)
#p.map(testProxy, proxyList)
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.map(testProxy, proxyList)
这里的问题是 Pool
,而不是 global
。
在函数范围内追加到列表(可变对象)时,该列表也会在全局范围内发生变化。 (实际上,您甚至不必使用 global
关键字:如果函数在其自身作用域中找不到变量,它会自动在全局作用域中查找。)注意一个小 "gotcha" 在下面的代码中,因为 map
是一个类似生成器的对象:
x = []
def add_to_x(i):
x.append(i)
if __name__ == '__main__':
y = map(add_to_x, [1, 2])
print(x) # still []
list(y)
print(x) # now [1, 2]
以下带有 Pool
的简单示例虽然不起作用:
from multiprocessing import Pool
x = []
def add_to_x(i):
x.append(i)
if __name__ == '__main__':
p = Pool(2)
list(p.map(add_to_x, [1, 2]))
print(x) # prints [] !
为什么? Python multiprocessing global variable updates not returned to parent 的答案具有启发性:这里是相关部分:
When you use
multiprocessing
to open a second process, an entirely new instance of Python, with its own global state, is created. That global state is not shared, so changes made by child processes to global variables will be invisible to the parent process.
您可以通过多种方式解决这个问题。一种方法是将 testProxy
更改为 is_good_proxy
,这将 return 一个布尔值。然后您可以在主循环中应用附加逻辑。