Nicht laden von Dateien mit pickle und mehrere Module
Ich versuche einen Benutzer anzulegen-system, die nutzt eine Einstellung und das Gui-Modul, und wenn das GUI-Modul Anfragen für die Datei zu laden, bis mit Gurke, bekomme ich immer ein Attribut Fehler. dies ist aus den Modul Einstellungen:
import pickle
import hashlib
class User(object):
def __init__(self, fname, lname, dob, gender):
self.firstname = fname
self.lastname = lname
self._dob = dob
self.gender = gender
self.type = 'General'
self._username = ''
self._hashkey = ''
def Report(self):
print("Full Name: {0} {1}\nDate of Birth: {2}\nGender: {3}\nAccess Level: {4}".format(self.firstname,self.lastname, self._dob, self.gender, self.type))
print(self._username)
def Genusername(self):
self._username = str(str(self._dob)[:2] + self.firstname[:2] + self.lastname[:2])
saveUsers(users)
def Genhashkey(self, password):
encoded = password.encode('utf-8','strict')
return hashlib.sha256(encoded).hexdigest()
def Verifypassword(self, password):
if self._hashkey == self.Genhashkey(password):
return True
else:
return False
class SAdmin(User):
def __init__(self, fname, lname, dob, gender):
super().__init__(fname, lname, dob, gender)
self.type = 'Stock Admin'
class Manager(User):
def __init__(self, fname, lname, dob, gender):
super().__init__(fname, lname, dob, gender)
self.type = 'Manager'
def saveUsers(users):
with open('user_data.pkl', 'wb') as file:
pickle.dump(users, file, -1) # PICKLE HIGHEST LEVEL PROTOCOL
def loadUsers(users):
try:
with open('user_data.pkl', 'rb') as file:
temp = pickle.load(file)
for item in temp:
users.append(item)
except IOError:
saveUsers([])
def userReport(users):
for user in users:
print(user.firstname, user.lastname)
def addUser(users):
fname = input('What is your First Name?\n > ')
lname = input('What is your Last Name?\n > ')
dob = int(input('Please enter your date of birth in the following format, example 12211996\n> '))
gender = input("What is your gender? 'M' or 'F'\n >")
level = input("Enter the access level given to this user 'G', 'A', 'M'\n > ")
password = input("Enter a password:\n > ")
if level == 'G':
usertype = User
if level == 'A':
usertype = SAdmin
if level == 'M':
usertype = Manager
users.append(usertype(fname, lname, dob, gender))
user = users[len(users)-1]
user.Genusername()
user._hashkey = user.Genhashkey(password)
saveUsers(users)
def deleteUser(users):
userReport(users)
delete = input('Please type in the First Name of the user do you wish to delete:\n > ')
for user in users:
if user.firstname == delete:
users.remove(user)
saveUsers(users)
def changePass(users):
userReport(users)
change = input('Please type in the First Name of the user you wish to change the password for :\n > ')
for user in users:
if user.firstname == change:
oldpass = input('Please type in your old password:\n > ')
newpass = input('Please type in your new password:\n > ')
if user.Verifypassword(oldpass):
user._hashkey = user.Genhashkey(newpass)
saveUsers(users)
else:
print('Your old password does not match!')
def verifyUser(username, password):
for user in users:
if user._username == username and user.Verifypassword(password):
return True
else:
return False
if __name__ == '__main__':
users = []
loadUsers(users)
- und dies ist das GUI-Modul:
from PyQt4 import QtGui, QtCore
import Settings
class loginWindow(QtGui.QDialog):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.lbl1 = QtGui.QLabel('Username')
self.lbl2 = QtGui.QLabel('Password')
self.username = QtGui.QLineEdit()
self.password = QtGui.QLineEdit()
self.okButton = QtGui.QPushButton("OK")
self.okButton.clicked.connect(self.tryLogin)
self.cancelButton = QtGui.QPushButton("Cancel")
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(self.lbl1, 1, 0)
grid.addWidget(self.username, 1, 1)
grid.addWidget(self.lbl2, 2, 0)
grid.addWidget(self.password, 2, 1)
grid.addWidget(self.okButton, 3, 1)
grid.addWidget(self.cancelButton, 3, 0)
self.setLayout(grid)
self.setGeometry(300, 300, 2950, 150)
self.setWindowTitle('Login')
self.show()
def tryLogin(self):
print(self.username.text(), self.password.text())
if Settings.verifyUser(self.username.text(),self.password.text()):
print('it Woks')
else:
QtGui.QMessageBox.warning(
self, 'Error', 'Incorrect Username or Password')
class Window(QtGui.QMainWindow):
def __init__(self):
super().__init__()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
users = []
Settings.loadUsers(users)
if loginWindow().exec_() == QtGui.QDialog.Accepted:
window = Window()
window.show()
sys.exit(app.exec_())
jeder Benutzer einer Klasse und werden dann in eine Liste und dann wird die Liste gespeichert, mit Gurke, wenn ich laden Sie einfach die Datei mit den Einstellungen und überprüfen Sie bei der Anmeldung alles funktioniert einwandfrei, aber wenn ich öffnen Sie die GUI-Modul und versuchen, stellen Sie sicher, es lässt mich nicht, die Fehler, die ich immer bin:
Traceback (most recent call last):
File "C:\Users`Program\LoginGUI.py", line 53, in <module>
Settings.loadUsers(users)
File "C:\Users\Program\Settings.py", line 51, in loadUsers
temp = pickle.load(file)
AttributeError: Can't get attribute 'Manager' on <module '__main__' (built-in)>
- Ich weiß nicht, ob dies Ihr problem, aber Sie brauchen nicht zu
close
eine Datei, wenn Sie es geöffnet haben, mitwith
. Der Kontext-manager zu schließen wird es automatisch für Sie, wenn die mit block enden. Auch IhreverifyUser
- Methode funktioniert nicht richtig. Es immer nur sieht auf den ersten Benutzer in der Liste Benutzer. - Danke für das feedback!, und ja, ich habe nur versucht, es mit einem Benutzer, ich werde wiederholen, dass wissen Sie, warum ich bin immer der Fehler?
- Können Sie nach dem Inhalt der user_data.pkl-Datei, vorausgesetzt, es ist eine test-Daten, die in dieser Phase?
€•Ñ ]”Œ__main__”ŒManager”“”)}”’”}”(Œlastname”ŒHammer”Œgender”ŒM”Œ_dob”JüxËŒ_hashkey”Œ@99b3bcf690e653a177c602dd9999093b9eb29e50a3af9a059af3fcbfab476a16”Œ _username”Œ30JaHa”Œtype”hŒ firstname”ŒJack”uba.
Es ist eine Gurke-Datei, so hats ja, wie es aussieht, ist es ein Objekt mit Vorname,Nachname, Geburtsdatum, Benutzername, hashkey(Passwort), und acceslevel- Recht, drei weitere Fragen - werden Sie Ihre Benutzer-Objekte, die aus einer Klasse namens-Manager? Ist dieses definiert in der Einstellung Modul? Wie hast du eigentlich erstellen user_data.pkl?
- es gibt eine main-Klasse namens " user dann Unterklassen dieser ist aus dem manager-Unterklasse und ja die Klassen sind alle geschaffen, die im Modul Einstellungen:
def saveUsers(users): with open('user_data.pkl', 'wb') as file: pickle.dump(users, file, -1)
und Sie sind geladen, die von dieser Funktion:def loadUsers(users): try: with open('user_data.pkl', 'rb') as file: temp = pickle.load(file) for item in temp: users.append(item) except IOError: saveUsers([])
- OK danke, ich denke, dass der relevante code nicht die details zu Ihrem login-Fenster, sondern die Klassen-Definitionen für einzelne Benutzer. Wie groß ist dein Modul Einstellungen? Ist es klein genug, um für Sie zu Bearbeiten die Frage, und fügen Sie das gesamte Modul statt nur die drei Funktionen und die name__=='__main' - Klausel?
- okay zugegeben das vollständige Modul-dort gehen Sie, es ist nicht, dass große tbh
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das Problem ist, dass Sie Beizen definierten Objekte in den Einstellungen eigentlich laufen Sie die "Einstellungen" - Modul, dann versuchen Sie zu unpickle die Objekte aus der
GUI
Modul.Denken Sie daran, dass die Gurke nicht wirklich speichern Informationen darüber, wie eine Klasse/Objekt aufgebaut ist, und benötigt Zugriff auf die Klasse, wenn unpickling. Sehen wiki auf mit Gurke für mehr details.
In der pkl Daten, die Sie sehen, dass das Objekt, auf das verwiesen wird, ist
__main__.Manager
, als Sie die "Einstellungen" - Modul wurde main, wenn Sie erstellt die pickle-Datei (D. H., Sie lief die "Einstellungen" - Modul als Haupt-script zum aufrufen deraddUser
- Funktion).Dann versuchen Sie unpickling in 'Gui' - so dass das Modul hat den Namen
__main__
, und Sie importieren die Einstellung in das Modul. So wird natürlich der Manager-Klasse wird tatsächlichSettings.Manager
. Aber die pkl-Datei dies nicht weiß, und sieht für die Manager-Klasse in__main__
, und wirft einen AttributeError weil es ihn nicht gibt (Settings.Manager
tut, aber__main__.Manager
nicht).Hier ist eine minimale code-set unter Beweis stellen.
Den
class_def.py
Modul:Führen Sie die oben zu generieren, die die pickle-Daten.
Die
main_module.py
Modul:Führen Sie die oben, um zu versuchen zu öffnen, die die pickle-Datei, und diese wirft etwa die gleichen Fehler, die Sie sahen. (Etwas anders, aber ich vermute, das ist, weil ich bin auf Python 2.7)
Die Lösung ist entweder:
Settings.addUser
von der GUI, oderclass_def.main
aus main_module). Dies bedeutet, dass die pkl-Datei speichern Sie die Objekte alsSettings.Manager
oderclass_def.Foo
, die dann in derGUI
`main_module` namespace.Option 1 Beispiel:
Option 2 Beispiel:
Lesen Sie bitte zuerst die Antwort erwähnt zehnpaard zu wissen, der Grund für das Attribut error. Andere als die Lösung, die er bereits zur Verfügung gestellt, in
python3
können Sie diepickle.Unpickler
- Klasse und überschreiben Sie diefind_class
- Methode, wie unten erwähnt:Wenn Sie eine Klasse definiert, die außerhalb der module, deren Gegenstand ist in Gurke-Daten,
man importiert die Klasse