Intenté reescribir un código de lectura csv para poder ejecutarlo en varios núcleos en Python 3.2.2. Traté de usar el Pool
objeto de multiprocesamiento, que adapté de ejemplos de trabajo (y ya me funcionó para otra parte de mi proyecto). Me encontré con un mensaje de error que encontré 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 forma de solucionar este problema?
python
python-3.x
multiprocessing
pool
László
fuente
fuente
None
debido a problemas de alcance.Class SomeClass(object):
a pesar de que TENÍA explícitamente una salida en mi clase. Una vez que eliminé la herenciaobject
funcionó. No tengo idea de por qué, entonces YMMVRespuestas:
El problema está en esta línea:
with pattern.findall(row) as f:
Estás usando la
with
declaración. Requiere un objeto con métodos__enter__
y__exit__
. Peropattern.findall
devuelve alist
,with
intenta almacenar el__exit__
método, pero no puede encontrarlo y genera un error. Solo usaen lugar.
fuente
No es el problema del autor de la pregunta en esta instancia, 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 SomeContextManager() as foo: #works because a new object is referenced...
no
with SomeContextManager as foo: #AttributeError because the class is referenced
Me atrapa de vez en cuando y termino aquí -__-
fuente
El error también ocurre al intentar utilizar el
with multiprocessing.Pool() as pool: # ...
con una versión de Python que es demasiado antigua (como Python 2.X) y no admite el uso
with
junto con grupos de multiprocesamiento.(Consulte esta respuesta https://stackoverflow.com/a/25968716/1426569 a otra pregunta para obtener más detalles)
fuente
La razón detrás de este error es: la aplicación Flask ya se está ejecutando, no se ha cerrado y, en medio de eso, intentamos iniciar otra instancia mediante: con app.app_context (): #Code Antes de usar esto con la declaración que necesitamos hacer asegúrese de que el alcance de la aplicación en ejecución anterior esté cerrado.
fuente