Как устранить неполадку "AttributeError: __exit__" в многопроцессорной обработке в Python?
Я попытался переписать некоторый код для чтения csv, чтобы иметь возможность запускать его на нескольких ядрах в Python 3.2.2. Я пытался использовать объект Pool
многопроцессорности, который я адаптировал из рабочих примеров (и уже работал для меня для другой части моего проекта). Я столкнулся с сообщением об ошибке, которое мне было трудно расшифровать и устранить.
Ошибка:
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__
Соответствующий код:
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)
Какой хороший способ устранить это?
Ответы
Ответ 1
Проблема в этой строке:
with pattern.findall(row) as f:
Вы используете with
выражением. Требуется объект с __enter__
и __exit__
. Но pattern.findall
возвращает list
with
попытками сохранить __exit__
, но не может найти его и выдает ошибку. Просто используйте
f = pattern.findall(row)
вместо.
Ответ 2
Проблема не в этом вопросе, но первый шаг устранения неполадок для общего "AttributeError: __exit__" должен быть уверен, что имеются скобки, например
with SomeEnterExitObject() as foo:
#works because a new object is referenced...
не
with SomeEnterExitObject as foo:
#AttributeError because the class is referenced
Время от времени ловит меня, и я заканчиваю здесь -__-
Ответ 3
Ошибка также возникает при попытке использовать
with multiprocessing.Pool() as pool:
# ...
с версией Python, который является слишком старым (как Python 2.x) и не поддерживает использование with
вместе с многопроцессорными бассейнами.
(Смотрите этот ответ fooobar.com/questions/5737/... на другой вопрос для более подробной информации)
Ответ 4
Причиной этой ошибки является то, что приложение Flask уже запущено, не закрылось, и в середине этого мы пытаемся запустить другой экземпляр с помощью: app.app_context(): #Code Прежде чем использовать это с оператором, нам нужно сделать Убедитесь, что область предыдущего запущенного приложения закрыта.
Ответ 5
Да, чтобы обойти это в моем случае, я просто присвоил свою переменную "with" обычной переменной, которая имела более короткое имя. Работал на меня.