Contexte:objet de partage entre les fils produit NoneType
Je travaille sur un robot web qui génère 7 fils de discussion, chaque requête à une URL unique pour un fichier XML. Lorsque chaque requête reçoit une réponse, il se que la réponse dans un arbre XML comme ceci:
conn = http.client.HTTPSConnection(host = uHost, port = uPort)
conn.request('GET', url = '/some/url/file.xml')
resp = conn.getresponse()
tree = xml.etree.ElementTree.parse(resp)
Lorsque chaque thread est démarré, il est donné un queue.Queue()
comme argument, pour qu'il puisse mettre le tree
en si __main__
est le seul thread à écrire des fichiers. En continuant d'en haut:
__main__
def receive(q):
while True:
try:
uTree = q.get()
uTree.write('/some/path/file.xml')
except queue.Empty:
pass
a donné naissance à
conn = http.client.HTTPSConnection(host = uHost, port = uPort)
conn.request('GET', url = '/some/url/file.xml')
resp = conn.getresponse()
tree = xml.etree.ElementTree.parse(resp)
q.put_nowait(tree)
Cependant, je commencé à recevoir AttributeError: 'NoneType' object has no attribute 'write'
lors de l'appel uTree.write()
. Un changement rapide de uTree.write()
-print(type(uTree))
a montré que les objets resteraient parfois intactes, d'autres fois ils deviennent NoneType
:
<class 'xml.etree.ElementTree.ElementTree'>
<class 'xml.etree.ElementTree.ElementTree'>
<class 'xml.etree.ElementTree.ElementTree'>
<class 'xml.etree.ElementTree.ElementTree'>
<class 'NoneType'>
<class 'NoneType'>
<class 'xml.etree.ElementTree.ElementTree'>
<class 'xml.etree.ElementTree.ElementTree'>
Questions:
Pourquoi les objets sont passés d'un threading.Thread()
à un queue.Queue()
[résidant sur __main__
] passer à NoneType
de manière incohérente?
Comment puis-je résoudre ce problème?
complet Code (le cas échéant):
main.py
import queue
import crawl # custom module
import threading
def crawler(query):
while True:
try:
query.connect()
break
except:
pass
def receive(q):
while True:
try:
uQuery = q.get()
uTree = uQuery.tree
uTree.write('/some/path/file.xml')
except queue.Empty:
pass
urls = ['/url1.xml', '/url2.xml', ...]
q = queue.Queue()
queries = [Query(url, q) for url in urls]
threads = [threading.Thread(target = crawler, args = (query,)) for query in queres]
for t in threads:
t.start()
receive(q)
crawl.py
import http.client
import xml.etree.ElementTree as ET
class Query:
def __init__(self, url, q):
self.url = url
self.queue = q
self.tree = None
def connect():
conn = http.Client.HTTPConnect(host = 'something.com', port = '80')
conn.request('GET', url = self.url)
resp = conn.getresponse()
self.tree = ET.parse(resp)
self.queue.put_nowait(self)
conn.close()