[Tutor] How to parse large files
Peter Otten
__peter__ at web.de
Sun Nov 1 14:19:25 EST 2015
Danny Yoo wrote:
>> AttributeError Traceback (most recent call
>> last) <ipython-input-3-f1c2a78eeb9a> in <module>()
>> ----> 1 with shelve.open("diz5") as db:
>> 2 with open("tmp1.txt") as instream:
>> 3 for line in instream:
>> 4 assert line.count("\t") == 1
>> 5 key, _tab, value = line.rstrip("\n").partition("\t")
>>
>> AttributeError: DbfilenameShelf instance has no attribute '__exit__'
>
>
> The error that you're seeing is on this line:
>
> with shelve.open("diz5") as db:
>
> so we should focus our efforts to know why this line is failing.
>
>
> The with statement in Python has a requirement, that the resource
> supports context management. Context managers have to have a few
> methods, according to:
>
> https://docs.python.org/3/reference/compound_stmts.html#the-with-statement
>
> https://docs.python.org/3/reference/datamodel.html#context-managers
>
>
> However, the error message reports that it can't find a method that
> it's looking for, "__exit__". it looks like shelves don't have the
> methods "__enter__" or "__exit__", which context managers must have.
>
> It looks like a deficiency in 'shelve', but one that we can work
> around without too much difficulty.
You need 3.4 or higher to use with... Quoting
<https://docs.python.org/dev/library/shelve.html#shelve.Shelf>:
"""
class shelve.Shelf(dict, protocol=None, writeback=False,
keyencoding='utf-8')
...
Changed in version 3.4: Added context manager support.
"""
> We can use the
> contextlib.closing() function to adapt a thing that knows how to
> close(), so that it works as a context manager.
> https://docs.python.org/3/library/contextlib.html#contextlib.closing
>
> It should be a matter of saying:
>
> import contextlib
> ...
> with contextlib.closing(shelve.open("diz5")) as db: ...
Yes, either use contextlib.closing() or close the db manually:
db = shelve.open("diz5")
try:
... # use db
finally:
db.close()
More information about the Tutor
mailing list