简体   繁体   中英

Pickle file not being written to properly

Here is my code:

 import pickle


 class User:
     def __init__(self, username, password):
         self.username = username
         self.password = password

     def set_password(self):
         self.password = input("Enter NEW password > ")

     def __get_password(self):
         return self.password

     def __get_username(self):
         return self.username

     def change_password(self):
         my_password = input("Enter your CURRENT password > ")
         if my_password == User.__get_password(self):
             self.set_password()
         else:
             print("Please try again")

     def display_details(self):
         print()
         print("Username and password")
         print("---------------------")
         print("username is: ", User.__get_username(self))
         print("password is: ", User.__get_password(self))
         print()

     def __repr__(self):
         return f'username: {self.username}'


 users = [User("MichaelPalin", "P4rr0t"), User("EricIdle", "M0nty"), User("TerryJones", "Pyth0n")]

 try:
     foo = pickle.load(open("users.pickle", "rb"))
 except (OSError, IOError) as f:
     foo = 3
     pickle.dump(foo, open("users.pickle", "wb"))

 # with open('users.pickle', 'wb') as f:
 #     pickle.dump(users, f)


 def find_user(name):
     for user in users:
         if user.username == name:
             return user


 def add_user():
     user = input("Enter NEW user > ")
     password = input(f"Enter password for {user} > ")
     users.append(User(user, password))


 def delete_user():
     delete_user = input("Enter the user you wish to remove > ")
     user = find_user(delete_user)
     if user:
         users.remove(user)
         print('done')
     else:
         print(f'user {delete_user} not found')


 def change_password():
     my_password = input("Enter your CURRENT password > ")
     change_password()


 def display_users():
     for user in users:
         print(user)


 def invalid_entry():  # Response for invalid entries to menu.
     print("Invalid entry, please try again")
     print()


 def menu():  # Display menu, prompt for and accept keyboard choice
     print("Please select one of the following:")
     print()
     print("Enter a if you want to add a new user")
     print("Enter d if you want to delete a user")
     print("Enter f if you want to find a user")
     print("Enter c if you want to change your password")
     print("Enter u if you want to display a list of users")
     print("Enter q if you want to Quit")
     choice = input("")
     return choice


 while True:
     menu_choice = menu()
     if menu_choice.lower() == "a":
         add_user()
     elif menu_choice.lower() == "d":
         delete_user()
     elif menu_choice.lower() == "f":
         find_user()
     elif menu_choice.lower() == "c":
         change_password()
     elif menu_choice.lower() == 'u':
         display_users()
     elif menu_choice.lower() == "q":
         print("Goodbye")
         with open('users.pickle', 'wb') as f:
             pickle.dump(users, f)
             quit()
     else:
         invalid_entry()

...but it's clearly not working properly, as though I can add a new user, once I restart my app, the new user is gone.

The first thing I want to do is read the pickle file in, right? But how can I read it in if it doesn't yet exist? So in that case that surely means I need to write it at first. But when I do that, I'm over-writing the existing file !

I tried using pickle.load as mentioned here , but it's just coming back "TypeError: load() takes exactly 1 positional argument (2 given)".

Any help please?

Edit: I made a couple of changes. The problem of over-writing the file is clearly not solved yet though.

I am not sure if I have got the answer but there was a little indentation issue (in my opinion) .. formatted code is as below.

import pickle


class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def set_password(self):
        self.password = input("Enter NEW password > ")

    def __get_password(self):
        return self.password

    def __get_username(self):
        return self.username

    def change_password(self):
        my_password = input("Enter your CURRENT password > ")
        if my_password == User.__get_password(self):
            self.set_password()
        else:
            print("Please try again")

    def display_details(self):
        print()
        print("Username and password")
        print("---------------------")
        print("username is: ", User.__get_username(self))
        print("password is: ", User.__get_password(self))
        print()

    def __repr__(self):
        return f'username: {self.username}'


users = [User("MichaelPalin", "P4rr0t"), User("EricIdle", "M0nty"), User("TerryJones", "Pyth0n")]


with open('mypickle.pickle', 'wb') as f:
    pickle.dump(users, f)


def find_user(name):
    for user in users:
        if user.username == name:
            return user


def display_users():
    for user in users:
        print(user)


def add_user():
    user = input("Enter NEW user > ")
    password = input(f"Enter password for {user} > ")
    users.append(User(user, password))
    with open('users.pickle', 'wb') as f:
        pickle.dump(users, f)


def delete_user():
    delete_user = input("Enter the user you wish to remove > ")
    user = find_user(delete_user)
    if user:
        users.remove(user)
        print('done')
    else:
        print(f'user {delete_user} not found')


def change_password():
    my_password = input("Enter your CURRENT password > ")
    change_password()


def invalid_entry():  # Response for invalid entries to menu.
    print("Invalid entry, please try again")
    print()


def menu():  # Display menu, prompt for and accept keyboard choice
    print("Please select one of the following:")
    print()
    print("Enter 1 if you want to add a new user")
    print("Enter 2 if you want to delete a user")
    print("Enter 3 if you want to change your password")
    print("Enter u if you want to display a list of users")
    print("Enter 4 if you want to Quit")
    choice = input("")
    return choice


while True:
    menu_choice = menu()
    if menu_choice == "1":
        add_user()
    elif menu_choice == "2":
        delete_user()
    elif menu_choice == "3":
        change_password()
    elif menu_choice.lower() == 'u':
        display_users()
    elif menu_choice == "4":
        print("Goodbye")
        quit()
    else:
        invalid_entry()

This gives me the expected output as below.

Please select one of the following:

Enter 1 if you want to add a new user
Enter 2 if you want to delete a user
Enter 3 if you want to change your password
Enter u if you want to display a list of users
Enter 4 if you want to Quit
1
Enter NEW user > TestUser
Enter password for TestUser > TestPassword
Please select one of the following:

Enter 1 if you want to add a new user
Enter 2 if you want to delete a user
Enter 3 if you want to change your password
Enter u if you want to display a list of users
Enter 4 if you want to Quit
u
username: MichaelPalin
username: EricIdle
username: TerryJones
username: TestUser
Please select one of the following:

Enter 1 if you want to add a new user
Enter 2 if you want to delete a user
Enter 3 if you want to change your password
Enter u if you want to display a list of users
Enter 4 if you want to Quit
4
Goodbye

To load the updated "users.pickle" file, I typed the below.

with open("/FullPathToPickleFile/users.pickle","rb") as Handle:
    pickle.load(Handle)

and this gave me the following output.

[username: MichaelPalin, username: EricIdle, username: TerryJones, username: TestUser]

As you can see the TestUser has been added. if you wanted to see the updated users as in the pickled file, I would have put the above mentioned two lines of code inside the display_users() as below.

def display_users():
    with open("/FullPathToPickleFile/users.pickle","rb") as Handle:
        print(pickle.load(Handle))

With these change, you should be able to update the users and see the updated list.

Is this what you wanted?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM