Wie behebt man einen "AttributeError: __exit__" bei der Mehrfachverarbeitung in Python?

87

Ich habe versucht, einen CSV-Lesecode neu zu schreiben, um ihn in Python 3.2.2 auf mehreren Kernen ausführen zu können. Ich habe versucht, das PoolObjekt der Mehrfachverarbeitung zu verwenden, das ich anhand von Arbeitsbeispielen angepasst habe (und bereits für einen anderen Teil meines Projekts für mich gearbeitet habe). Ich stieß auf eine Fehlermeldung, die ich nur schwer entschlüsseln und beheben konnte.

Der Fehler:

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__

Der relevante Code:

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)

Was ist ein guter Weg, um dies zu beheben?

László
quelle
1
In meinem Fall habe ich versehentlich einen Noneaufgrund von Scoping-Problemen bestanden.
ThorSummoner
Ich hatte dies, als ich eine Klasse deklarierte Class SomeClass(object):, obwohl ich explizit einen Exit in meiner Klasse hatte. Sobald ich die Vererbung entfernt habe, hat objectes funktioniert. Ich habe keine Ahnung warum, also YMMV
mpag

Antworten:

154

Das Problem liegt in dieser Zeile:

with pattern.findall(row) as f:

Sie verwenden die withAnweisung. Es erfordert ein Objekt mit __enter__und __exit__Methoden. pattern.findallGibt aber a zurück list, withversucht die __exit__Methode zu speichern , kann sie jedoch nicht finden und löst einen Fehler aus. Benutz einfach

f = pattern.findall(row)

stattdessen.

utdemir
quelle
62

In diesem Fall ist dies nicht das Problem des Fragestellers, aber der erste Schritt zur Fehlerbehebung für einen generischen "AttributeError: __exit__" sollte darin bestehen, sicherzustellen, dass die Klammern vorhanden sind, z

with SomeContextManager() as foo:
    #works because a new object is referenced...

nicht

with SomeContextManager as foo:
    #AttributeError because the class is referenced

Fängt mich von Zeit zu Zeit aus und ich lande hier -__-

Taschen und
quelle
9

Der Fehler tritt auch auf, wenn Sie versuchen, das zu verwenden

with multiprocessing.Pool() as pool:
   # ...

mit einer Python-Version, die zu alt ist (wie Python 2.X) und die Verwendung withzusammen mit Multiprocessing-Pools nicht unterstützt .

( Weitere Informationen finden Sie in dieser Antwort unter https://stackoverflow.com/a/25968716/1426569 für eine andere Frage.)

oseiskar
quelle
Ja! Funktioniert hervorragend mit Python 3.X
Sreekant Shenoy
0

Der Grund für diesen Fehler ist: Die Flask-App wird bereits ausgeführt, wurde nicht heruntergefahren und in der Mitte versuchen wir, eine andere Instanz zu starten, indem wir: mit app.app_context (): #Code Bevor wir dies mit der Anweisung verwenden, die wir machen müssen Stellen Sie sicher, dass der Bereich der zuvor ausgeführten App geschlossen ist.

SIDDHARTH SETHIA
quelle