2013-05-23 12 views
6

Ich versuche, ein einfaches Passwort speichern-Programm in Python, und es scheint ziemlich einfach, so frage ich mich, wenn ich Regal falsch verwende.Shelve-Modul in Python funktioniert nicht: "db-Typ kann nicht bestimmt werden"

ich die Haupt-Py-Datei:

import shelve 

passwords = shelve.open('./passwords_dict.py') 

choice = raw_input("Add password (a) or choose site (c)?") 

if choice[0] == 'a': 
    site_key = raw_input("Add for which site? ").lower() 
    userpass = raw_input("Add any info such as username, email, or passwords: ") 

    passwords[site_key] = userpass 

else: 
    site = raw_input("Which site? ").lower() 
    if site in passwords: 
     print "Info for " + site + ": " + passwords[site] 
    else: 
     print site, "doesn't seem to exist!" 

print "Done!" 

passwords.close() 

Und die andere Datei, passwords_dict.py, ist nur ein leeres Wörterbuch.

Aber wenn ich versuche, das Programm auszuführen, erhalte ich diese Fehlermeldung:

Traceback (most recent call last): 
File "passwords.py", line 3, in <module> 
passwords = shelve.open('passwords_dict.py') 
File "/usr/lib/python2.7/shelve.py", line 239, in open 
return DbfilenameShelf(filename, flag, protocol, writeback) 
File "/usr/lib/python2.7/shelve.py", line 223, in __init__ 
Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) 
File "/usr/lib/python2.7/anydbm.py", line 82, in open 
raise error, "db type could not be determined" 
anydbm.error: db type could not be determined 

Wenn ich versuche stattdessen anydbm zu verwenden, bekomme ich diesen Fehler:

Traceback (most recent call last): 
File "passwords.py", line 3, in <module> 
passwords = anydbm.open('passwords_dict.py') 
File "/usr/lib/python2.7/anydbm.py", line 82, in open 
raise error, "db type could not be determined" 
anydbm.error: db type could not be determined 

Und wenn ich versuche, benutze dbm stattdessen, bekomme ich diesen fehler:

Traceback (most recent call last): 
File "passwords.py", line 3, in <module> 
passwords = dbm.open('./passwords_dict.py') 
dbm.error: (2, 'No such file or directory') 

Was mache ich falsch? Gibt es eine andere Möglichkeit, ein Wörterbuch zu speichern und trotzdem Schlüssel mithilfe von Benutzereingaben zu extrahieren (anstatt des gesamten Wörterbuchs, was wohl die Beize ist)?

Antwort

5

Ich glaube, Sie verstehen nicht, wie das Modul funktioniert. Es öffnet eine Datenbankdatei. Wenn Sie versuchen, eine vorhandene Datei zu öffnen, die ein Python-Skript enthält, versucht sie herauszufinden, welchen Datenbanktyp die Datei enthält (da shelve mehrere Backend-Datenbanken unterstützt).

Ich denke, stattdessen wollen Sie so etwas wie diese:

import os 
import shelve 

curdir = os.path.dirname(__file__) 
passwords = shelve.open(os.path.join(curdir, 'password_db')) 

Dies wird eine neue Datei im selben Verzeichnis wie das Skript password_db.<db> genannt schaffen, wo <db> eine Implementierung spezifische Datenbank-Dateierweiterung ist.

0

Ich habe dieses Problem auch erlebt. Es scheint zu undokumentierten Bedingungen für das filename Argument von shelve.open verwandt zu sein. Es ist derzeit sehr intransparent (z. B. shelve.open("/tmp/tmphTTQLda") funktioniert, während shelve.open("/tmp/tmphTTQLd") nicht funktioniert). Fehler und Erfolg von variablen Dateinamen sind schwer vorherzusagen. Ich bat um eine Erklärung in Form einer Dokumentationsverbesserung bei http://bugs.python.org/issue23174.

In meinem Fall öffnet ein persistentes Diktat außerhalb shelve und übergibt es an shelve.Shelve funktioniert, z.

Code
a = dumbdbm.open(tempfile.mkstemp()[1]) 
b = shelve.Shelf(dict=a) 

und tun mit b, was Sie mit dem Rückgabewert von shelve.open getan haben würde.

+0

sorry, was seine tempfile? das funktioniert auch wenn die tempdatei bereits existiert? –

+0

'tempfile' ist ein Standard-Python-Modul. 'Tempdatei.mkstemp' sollte per Definition eine nicht existierende Datei erstellen. –

0

Es gibt einen Fehler mit anydb https://bugs.python.org/issue13007, der die richtige Identifikation für gdbm Dateien nicht verwenden konnte.

Also, wenn Sie eine gültige gdbm Datei mit shelve versuchen, zu öffnen und thorwing, dass die Verwendung Fehler Sie stattdessen:

mod = __import__("gdbm") 
    file = shelve.Shelf(mod.open(filename, flag)) 

Weitere Informationen zu dieser Frage: shelve db type could not be determined, whichdb is not recognizing gdb

+0

Warum nicht einfach 'gdbm' importieren, dann später' file = shelve.Shelf (gdbm.open (Dateiname, Flag)) ', was viel pythischer zu sein scheint? – cnaak