2013-05-23 8 views
6

Próbuję zrobić prosty program do przechowywania haseł w Pythonie, i wydaje się to dość proste, więc zastanawiam się, czy używam źle odkładanej półki.Moduł półki w pytonie nie działa: "nie można określić typu db"

mam główny plik .py:

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() 

a drugi plik passwords_dict.py, jest tylko pusty słownik.

Ale gdy próbuję uruchomić program, otrzymuję ten błąd:

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 

Kiedy próbuję użyć anydbm zamiast, otrzymuję ten błąd:

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 

I gdy próbuję zamiast tego użyj dbm, otrzymuję ten błąd:

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') 

Co robię źle? Czy istnieje inny sposób na przechowywanie słownika i wciąż można wydobywać klucze za pomocą danych wprowadzanych przez użytkownika (zamiast całego słownika, który, jak sądzę, jest tym, co robi piksel)?

Odpowiedz

5

Myślę, że nie rozumiesz, jak działa moduł półkowy. Otwiera plik bazy danych. Kiedy próbujesz otworzyć istniejący plik zawierający skrypt w języku Python, próbuje wykryć, jaki typ bazy danych zawiera plik (ponieważ shelve obsługuje wiele baz danych backendu).

myślę zamiast chcesz coś takiego:

import os 
import shelve 

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

stworzy nowy plik w tym samym katalogu, co plik skryptu o nazwie password_db.<db> gdzie <db> to rozszerzenie pliku bazy danych realizacja specyficznych.

0

Wystąpił również ten problem. Wydaje się być związane z nieudokumentowanymi warunkami dla argumentu filename z shelve.open. Obecnie jest on bardzo nieprzejrzysty (np. shelve.open("/tmp/tmphTTQLda") działa, gdy nie ma shelve.open("/tmp/tmphTTQLd")). Niepowodzenia i powodzenie zmiennych nazw plików są trudne do przewidzenia. Poprosiłem o wyjaśnienie w formie ulepszenia dokumentacji pod numerem http://bugs.python.org/issue23174.

W moim przypadku otworzenie trwałego dict poza numerem shelve i przekazanie go do shelve.Shelve działa, np. Kod

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

i zrobić z b, co można zrobić z wartości zwracanej shelve.open.

+0

Niestety, co jest jego pliku tymczasowego? działa to również, jeśli tempfile już istnieje? –

+0

'tempfile' to standardowy moduł python. 'tempfile.mkstemp' powinien z definicji utworzyć nieistniejący plik. –

0

Istnieje jeden błąd z anydb https://bugs.python.org/issue13007, który nie może użyć właściwej identyfikacji dla plików gdbm.

Więc jeśli próbujesz otworzyć prawidłowy plik gdbm z półki i jest thorwing że wykorzystanie tego błędu zamiast:

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

Więcej informacji na ten temat: shelve db type could not be determined, whichdb is not recognizing gdb

+0

Dlaczego nie po prostu "zaimportować gdbm", a następnie 'file = shelve.Shelf (gdbm.open (filename, flag))', który wydaje się być bardziej pythonic? – cnaak

Powiązane problemy