Bagaimana cara memecahkan masalah "AttributeError: __exit__" di multiproccesing dengan Python?

87

Saya mencoba menulis ulang beberapa kode pembacaan csv untuk dapat menjalankannya pada banyak inti dengan Python 3.2.2. Saya mencoba menggunakan Poolobjek multiprocessing, yang saya adaptasi dari contoh kerja (dan sudah bekerja untuk saya untuk bagian lain dari proyek saya). Saya mendapat pesan kesalahan yang menurut saya sulit diuraikan dan dipecahkan.

Kesalahannya:

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__

Kode yang relevan:

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)

Apa cara yang baik untuk memecahkan masalah ini?

László
sumber
1
Dalam kasus saya, saya tidak sengaja lulus Nonekarena masalah pelingkupan.
ThorSummoner
Saya mengalami ini ketika saya mendeklarasikan kelas seolah Class SomeClass(object):-olah saya DID secara eksplisit memiliki jalan keluar di kelas saya. Setelah saya menghapus warisan dari objectitu berhasil. Saya tidak tahu mengapa, jadi YMMV
mpag

Jawaban:

155

Masalahnya ada di baris ini:

with pattern.findall(row) as f:

Anda menggunakan withpernyataan itu. Ini membutuhkan objek dengan __enter__dan __exit__metode. Tetapi pattern.findallmengembalikan a list, withmencoba menyimpan __exit__metode, tetapi tidak dapat menemukannya, dan menimbulkan kesalahan. Gunakan saja

f = pattern.findall(row)

sebagai gantinya.

utdemir
sumber
63

Ini bukan masalah penanya dalam hal ini, tetapi langkah pemecahan masalah pertama untuk "AttributeError: __exit__" generik harus memastikan tanda kurung ada di sana, misalnya

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

tidak

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

Menangkap saya dari waktu ke waktu dan saya berakhir di sini -__-

Pocketsand
sumber
9

Kesalahan juga terjadi saat mencoba menggunakan

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

dengan versi Python yang terlalu tua (seperti Python 2.X) dan tidak mendukung penggunaan withbersama dengan kumpulan multiprosesing.

(Lihat jawaban ini https://stackoverflow.com/a/25968716/1426569 untuk pertanyaan lain untuk lebih jelasnya)

oseiskar.dll
sumber
Ya! Bekerja dengan baik pada Python 3.X
Sreekant Shenoy
-1

Alasan dibalik kesalahan ini adalah: Aplikasi Flask sudah berjalan, belum ditutup dan di tengah-tengah itu kita mencoba untuk memulai instance lain dengan: dengan app.app_context (): #Code Sebelum kita menggunakan ini dengan pernyataan yang perlu kita buat pastikan cakupan aplikasi yang berjalan sebelumnya ditutup.

SETHIA SIDDHARTH
sumber