"with" statement und "shelve" geht nicht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Nebelhom
User
Beiträge: 155
Registriert: Mittwoch 19. Mai 2010, 01:31

Code: Alles auswählen

IDLE 2.6.5  
>>> import shelve
>>> t = 'test'
>>> with shelve.open('test') as db:
    db['t'] = t 

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    with shelve.open('test') as db:
  File "C:\Python26\lib\shelve.py", line 239, in open
    return DbfilenameShelf(filename, flag, protocol, writeback)
  File "C:\Python26\lib\shelve.py", line 223, in __init__
    Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)
  File "C:\Python26\lib\anydbm.py", line 83, in open
    return mod.open(file, flag, mode)
  File "C:\Python26\lib\dbhash.py", line 19, in open
    return bsddb.hashopen(file, flag, mode)
  File "C:\Python26\lib\bsddb\__init__.py", line 361, in hashopen
    d.open(file, db.DB_HASH, flags, mode)
DBPermissionsError: (1, 'Operation not permitted')
bzw. in eclipse

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\Nebelhom\workspace\pyChemDataManager\src\compound.py", line 172, in <module>
    with shelve.open('test.db') as db:
AttributeError: DbfilenameShelf instance has no attribute '__exit__'
Ich dachte das 'with' statement ist fuer alle open methoden in den bei der installation mitgelieferten modulen... Habe ich da was verplant oder wird die '__exit__' methode in einer spaeteren Version hinzugefuegt?

PEP 343 hat mich auch nicht wirklich schlauer gemacht... Habe ich da mal wieder die Philosophie hinter einem neuen statement nicht verstanden?

Ach ja, ich benutze python 2.6. Danke schonmal fuer die Aufklaerung
BlackJack

@Nebelhom: Was `shelve.open()` da zurückliefert erfüllt halt offensichtlich nicht die Erwartungen von ``with``. Ein Bugreport ist sicher mittlerweile erstellt worden, also hilft wahrscheinlich nur das Implementieren einer Lösung und Einreichen des Patches. :-)

Und nein -- nicht jede `open()`-Funktion oder -Methode muss jetzt zwingend etwas liefern was `__enter__()` und `__exit__()` entsprechend implementiert. Das tun dafür aber auch Objekte die nichts mit `open()` oder `close()` zu tun haben, wie zum Beispiel Lock-Objekte aus dem `threading`-Modul.

`contextlib.closing()` könnte eine Lösung für Dich sein.
Antworten