วิธีแก้ปัญหา“ AttributeError: __exit__” ในการเล่นหลายส่วนใน Python


87

ฉันพยายามเขียนโค้ดการอ่าน 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
ในกรณีของฉันฉันบังเอิญผ่านNoneเนื่องจากปัญหาการกำหนดขอบเขต
ThorSummoner

ฉันมีสิ่งนี้เมื่อฉันประกาศชั้นเรียนClass SomeClass(object):แม้ว่าฉันจะมีทางออกในชั้นเรียนอย่างชัดเจนก็ตาม เมื่อฉันลบมรดกจากobjectมันได้ผล ฉันไม่รู้ว่าทำไม YMMV
mpag

คำตอบ:


155

ปัญหาอยู่ในบรรทัดนี้:

with pattern.findall(row) as f:

คุณกำลังใช้withคำสั่ง มันต้องใช้วัตถุ__enter__และ__exit__วิธีการ แต่pattern.findallผลตอบแทนlist, withพยายามที่จะเก็บ__exit__วิธี แต่ก็ไม่สามารถหาได้และก่อให้เกิดข้อผิดพลาด เพียงแค่ใช้

f = pattern.findall(row)

แทน.


63

ไม่ใช่ปัญหาของผู้ถามในกรณีนี้ แต่ขั้นตอนแรกในการแก้ปัญหาสำหรับ "AttributeError: __exit__" ทั่วไปควรตรวจสอบให้แน่ใจว่ามีวงเล็บอยู่เช่น

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

ไม่

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

แอบมองฉันเป็นระยะ ๆ แล้วมาจบที่นี่ -__-


9

ข้อผิดพลาดยังเกิดขึ้นเมื่อพยายามใช้ไฟล์

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

ด้วยเวอร์ชัน Python ที่เก่าเกินไป (เช่น Python 2.X) และไม่รองรับการใช้ withร่วมกับพูลการประมวลผลหลายตัว

(ดูคำตอบนี้https://stackoverflow.com/a/25968716/1426569สำหรับคำถามอื่นสำหรับรายละเอียดเพิ่มเติม)


เออ! ทำงานได้ดีกับ Python 3.X
Sreekant Shenoy

-1

สาเหตุที่อยู่เบื้องหลังข้อผิดพลาดนี้คือ: แอป Flask กำลังทำงานอยู่แล้วยังไม่ได้ปิดตัวลงและในระหว่างนั้นเราพยายามเริ่มอินสแตนซ์อื่นโดย: ด้วย app.app_context (): #Code ก่อนที่เราจะใช้สิ่งนี้ด้วยคำสั่งที่เราต้องทำ ตรวจสอบให้แน่ใจว่าขอบเขตของแอปที่ทำงานก่อนหน้านี้ปิดอยู่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.