lock - python pool thread
¿Cómo solucionar un "AttributeError:__exit__" en multiproccesing en Python? (2)
El problema está en esta línea:
with pattern.findall(row) as f:
Estás usando la declaración with
. Requiere un objeto con métodos __enter__
y __exit__
. Pero pattern.findall
devuelve una list
, with
intentos de almacenar el método __exit__
, pero no puede encontrarlo y genera un error. Solo usa
f = pattern.findall(row)
en lugar.
Traté de reescribir algún código de lectura csv para poder ejecutarlo en múltiples núcleos en Python 3.2.2. Traté de usar el objeto Pool
de multiprocesamiento, que adapté de ejemplos prácticos (y que ya funcionó para mí en otra parte de mi proyecto). Me encontré con un mensaje de error que me pareció difícil de descifrar y solucionar.
El error:
Traceback (most recent call last):
File "parser5_nodots_parallel.py", line 256, in <module>
MG,ppl = csv2graph(r)
File "parser5_nodots_parallel.py", line 245, in csv2graph
node_chunks)
File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/multiprocessing/pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/multiprocessing/pool.py", line 552, in get
raise self._value
AttributeError: __exit__
El código relevante:
import csv
import time
import datetime
import re
from operator import itemgetter
from multiprocessing import Pool
import itertools
def chunks(l,n):
"""Divide a list of nodes `l` in `n` chunks"""
l_c = iter(l)
while 1:
x = tuple(itertools.islice(l_c,n))
if not x:
return
yield x
def csv2nodes(r):
strptime = time.strptime
mktime = time.mktime
l = []
ppl = set()
pattern = re.compile(r"""[A-Za-z0-9"/]+?(?=[,/n])""")
for row in r:
with pattern.findall(row) as f:
cell = int(f[3])
id = int(f[2])
st = mktime(strptime(f[0],''%d/%m/%Y''))
ed = mktime(strptime(f[1],''%d/%m/%Y''))
# collect list
l.append([(id,cell,{1:st,2: ed})])
# collect separate sets
ppl.add(id)
return (l,ppl)
def csv2graph(source):
MG=nx.MultiGraph()
# Remember that I use integers for edge attributes, to save space! Dic above.
# start: 1
# end: 2
p = Pool()
node_divisor = len(p._pool)
node_chunks = list(chunks(source,int(len(source)/int(node_divisor))))
num_chunks = len(node_chunks)
pedgelists = p.map(csv2nodes,
node_chunks)
ll = []
ppl = set()
for l in pedgelists:
ll.append(l[0])
ppl.update(l[1])
MG.add_edges_from(ll)
return (MG,ppl)
with open(''/Users/laszlosandor/Dropbox/peers_prisons/python/codetenus_test.txt'',''r'') as source:
r = source.readlines()
MG,ppl = csv2graph(r)
¿Cuál es una buena manera de solucionar esto?
En este caso, no es el problema del solicitante, pero el primer paso de solución de problemas para un "AttributeError: __exit__" genérico debe ser asegurarse de que los corchetes estén allí, por ejemplo
with SomeEnterExitObject() as foo:
#works because a new object is referenced...
no
with SomeEnterExitObject as foo:
#AttributeError because the class is referenced
Me atrapa de vez en cuando y termino aquí -__-