Hoe een “AttributeError: __exit__” in multiproccesing in Python oplossen?

Ik heb geprobeerd wat csv-leescode te herschrijven om het op meerdere kernen in Python 3.2.2 te kunnen uitvoeren. Ik heb geprobeerd het Pool-object van multiprocessing te gebruiken, dat ik heb aangepast aan de hand van werkvoorbeelden (en al voor mij werkte voor een ander deel van mijn project). Ik kwam een foutmelding tegen die ik moeilijk kon ontcijferen en oplossen.

De fout:

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__

De 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)

Wat is een goede manier om dit op te lossen?


Antwoord 1, autoriteit 100%

Het probleem zit in deze regel:

with pattern.findall(row) as f:

U gebruikt de with-instructie. Het vereist een object met de methoden __enter__en __exit__. Maar pattern.findallretourneert een list, withprobeert de methode __exit__op te slaan, maar kan het niet vinden het, en geeft een fout. Gebruik gewoon

f = pattern.findall(row)

in plaats daarvan.


Antwoord 2, autoriteit 41%

In dit geval is het niet het probleem van de vrager, maar de eerstestap voor probleemoplossing voor een generieke “AttributeError: __exit__” zou moeten zijn ervoor te zorgen dat de haakjes aanwezig zijn, bijvoorbeeld

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

niet

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

Betrapt me af en toe en ik eindig hier -__-


Antwoord 3, autoriteit 6%

De fout treedt ook op bij het gebruik van de

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

met een Python-versie die te oud is (zoals Python 2.X) en die het gebruik van withsamen met multiprocessing-pools niet ondersteunt.

(Zie dit antwoord https://stackoverflow.com/a/25968716/1426569op een andere vraag voor meer details )


Antwoord 4

De reden achter deze fout is:
Flask-app is al actief, is niet afgesloten en in het midden daarvan proberen we een andere instantie te starten door:
met app.app_context():
#Code
Voordat we dit met instructie gebruiken, moeten we ervoor zorgen dat het bereik van de vorige actieve app is gesloten.

Other episodes