web-dev-qa-db-fra.com

Comment dépanner un "AttributeError: __exit__" dans le traitement multiple en Python?

J'ai essayé de réécrire du code de lecture csv pour pouvoir l'exécuter sur plusieurs cœurs dans Python 3.2.2. J'ai essayé d'utiliser l'objet Pool du multitraitement, que je adapté d'exemples de travail (et déjà travaillé pour moi pour une autre partie de mon projet). Je suis tombé sur un message d'erreur que j'ai eu du mal à déchiffrer et à résoudre.

L'erreur:

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__

Le code correspondant:

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)

Quel est un bon moyen de résoudre ce problème?

83
László

Le problème est dans cette ligne:

with pattern.findall(row) as f:

Vous utilisez l'instruction with. Il nécessite un objet avec __enter__ et __exit__ méthodes. Mais pattern.findall retourne un list, with tente de stocker le __exit__, mais il ne le trouve pas et génère une erreur. Juste utiliser

f = pattern.findall(row)

au lieu.

142
utdemir

Dans ce cas, ce n’est pas le problème du demandeur, mais le premier étape de dépannage pour un "AttributeError: __exit__" générique doit vérifier que les crochets sont présents, par exemple.

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

pas

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

Me surprend de temps en temps et je finis ici -__-

58
Pocketsand

L’erreur se produit également lorsqu’on essaie d’utiliser le

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

avec une version Python trop ancienne (comme Python 2.X) et ne prenant pas en charge l’utilisation de with avec des pools de multitraitement.).

(Voir cette réponse https://stackoverflow.com/a/25968716/1426569 à une autre question pour plus de détails)

8
oseiskar

La raison de cette erreur est la suivante: Flask app est déjà en cours d'exécution, n'est pas arrêté et au milieu de cela, nous essayons de démarrer une autre instance avec: avec app.app_context (): #Code Before nous utilisons cette déclaration avec nous devons nous assurer que la portée de la précédente application en cours d'exécution est fermée.

1
SIDDHARTH SETHIA