Python: 'NoneType' object has no attribute 'get_username'
Question: I'm working on a hangman program that also has user accounts objects. The
player can log in, create a new account, or view account details, all of which
work fine before playing the game. After the game has completed, the user's
wins and losses are updated. Before exiting the program, if I try to view the
account (the viewAcc function) I get the error:

    
    
    'NoneType' object has no attribute 'get_username'.
    

When I run the the program again, I can log in to the account, but when I view
the account info the wins and losses haven't been updated. Any help would be
appreciated, I have to turn this in for class in about 8 hours.

Heres the class code:

    
    
    class Account:
        def __init__(self, username, password, name, email, win, loss):
            self.__username = username
            self.__password = password
            self.__name = name
            self.__email = email
            self.__win = int(win)
            self.__loss = int(loss)
    
        def set_username (self, username):
            self.__username = username
    
        def set_password (self, password):
            self.__password = password
    
        def set_name (self, name):
            self.__name = name
    
        def set_email (self, email):
            self.__email = email
    
        def set_win (self, win):
            self.__win = win
    
        def set_loss (self, loss):
            self.__loss = loss
    
        def get_username (self):
            return self.__username
    
        def get_password (self):
            return self.__password
    
        def get_name (self):
            return self.__name
    
        def get_email (self):
            return self.__email
    
        def get_win (self):
            return self.__win
    
        def get_loss (self):
            return self.__loss
    

And here's my program's code:

    
    
    import random
    import os
    import Account
    import pickle
    import sys
    #List of images for different for different stages of being hanged
    STAGES = [
    '''
          ___________
         |/         |
         |          |
         |         
         |         
         |          
         |         
         |
         |
         |
    _____|______
    '''
    ,
    '''
          ___________
         |/         |
         |          |
         |        (o_o)
         |         
         |          
         |         
         |
         |
         |
    _____|______
    '''
    ,
    '''
          ___________
         |/         |
         |          |
         |        (o_o)
         |          | 
         |          |
         |         
         |
         |
         |
    _____|______
    '''
    ,
    '''
          ___________
         |/         |
         |          |
         |        (o_o)
         |          |/ 
         |          |
         |          
         |
         |
         |
    _____|______
    '''
    ,
    '''
          ___________
         |/         |
         |          |
         |        (o_o)
         |         \|/ 
         |          |
         |           
         |
         |
         |
    _____|______
    '''
    ,
    '''
          ___________
         |/         |
         |          |
         |        (o_o)
         |         \|/ 
         |          |
         |         / 
         |
         |
         |
    _____|______
    '''
    ,
    '''
        YOU DEAD!!!
          ___________
         |/         |
         |          |
         |        (X_X)
         |         \|/ 
         |          |
         |         / \ 
         |
         |
         |
    _____|______
    '''
    ]
    
    #used to validate user input
    ALPHABET = ['abcdefghijklmnopqrstuvwxyz']
    
    #Declares lists of different sized words
    fourWords = ['ties', 'shoe', 'wall', 'dime', 'pens', 'lips', 'toys', 'from', 'your', 'will', 'have', 'long', 'clam', 'crow', 'duck', 'dove', 'fish', 'gull', 'fowl', 'frog', 'hare', 'hair', 'hawk', 'deer', 'bull', 'bird', 'bear', 'bass', 'foal', 'moth', 'back', 'baby']
    fiveWords = ['jazzy', 'faker', 'alien', 'aline', 'allot', 'alias', 'alert', 'intro', 'inlet', 'erase', 'error', 'onion', 'least', 'liner', 'linen', 'lions', 'loose', 'loner', 'lists', 'nasal', 'lunar', 'louse', 'oasis', 'nurse', 'notes', 'noose', 'otter', 'reset', 'rerun', 'ratio', 'resin', 'reuse', 'retro', 'rinse', 'roast', 'roots', 'saint', 'salad', 'ruins']
    sixwords =  ['baboon', 'python',]
    
    
    def main():
        #Gets menu choice from user
        choice = menu()
    
        #Initializes dictionary of user accounts from file
        accDct = loadAcc()
    
        #initializes user's account
        user = Account.Account("", "", "", "", 0, 0)
    
        while choice != 0:
            if choice == 1:
               user = play(user)
            if choice == 2:
                createAcc(accDct)
            if choice == 3:
               user = logIn(accDct)
            if choice == 4:
                viewAcc(user)
            choice = menu()
    
        saveAcc(accDct)
    
    #Plays the game
    def play(user):
    
        os.system("cls") #Clears screen
        hangman = 0      #Used as index for stage view
        done = False    #Used to signal when game is finished
        guessed = ['']   #Holds letters already guessed
    
        #Gets the game word lenght from the user
        difficulty = int(input("Chose Difficulty/Word Length:\n"\
                               "1. Easy: Four Letter Word\n"\
                               "2. Medium: Five Letter Word\n"\
                               "3. Hard: Six Letter Word\n"\
                               "Choice: "))
        #Validates input                 
        while difficulty < 1 or difficulty > 3:
            difficulty = int(input("Invalid menu choice.\n"\
                                   "Reenter Choice(1-3): "))
    
        #Gets a random word from a different list depending on difficulty
        if difficulty == 1:
            word = random.choice(fourWords)
        if difficulty == 2:
            word = random.choice(fiveWords)
        if difficulty == 3:
            word = random.choice(sixWords)
    
        viewWord = list('_'*len(word))
        letters = list(word)
    
        while done == False:
    
            os.system("cls")
    
            print(STAGES[hangman])
            for i in range(len(word)):
                sys.stdout.write(viewWord[i])
                sys.stdout.write(" ")
            print()
            print("Guessed Letters: ")
            for i in range(len(guessed)):
                sys.stdout.write(guessed[i])
            print()
    
            guess = str(input("Enter guess: "))
            guess = guess.lower()
    
            while guess in guessed:
                guess = str(input("Already guessed that letter.\n"\
                                  "Enter another guess: "))
    
            while len(guess) != 1:
                guess = str(input("Guess must be ONE letter.\n"\
                                  "Enter another guess: "))
    
            while guess not in ALPHABET[0]:
                guess = str(input("Guess must be a letter.\n"\
                         "Enter another guess: "))
    
            if guess not in letters:
                hangman+=1
    
            for i in range(len(word)):
                if guess in letters[i]:
                    viewWord[i] = guess
    
            guessed += guess
    
            if '_' not in viewWord:
                print ("Congratulations! You correctly guessed",word)
                done = True
    
                win = user.get_win()
                win += 1
                username = user.get_username()
                password = user.get_password()
                name = user.get_name()
                email = user.get_email()
                loss = user.get_loss()
                user = Account.Account(username, password, name, email, win, loss)
    
            if hangman == 6:
                os.system("cls")
                print()
                print(STAGES[hangman])
                print("You couldn't guess the word",word.upper(),"before being hanged.")
                print("Sorry, you lose.")
                done = True
    
                loss = user.get_loss()
                loss += 1
                username = user.get_username()
                password = user.get_password()
                name = user.get_name()
                email = user.get_email()
                win = user.get_win()
                user = Account.Account(username, password, name, email, win, loss)
    
    
    
    
    
    
    #Loads user accounts from file
    def loadAcc():
        try:
            iFile = open('userAccounts.txt', 'rb')
    
            accDct = pickle.load(iFile)
    
            iFile.close
    
        except IOError:
            accDct = {}
    
        return accDct
    
    #Displays the menu        
    def menu():
        os.system('cls')
        print("Welcome to Karl-Heinz's Hangman")
        choice = int(input("1. Play Hangman\n"\
                           "2. Create Account\n"\
                           "3. Log In\n"\
                           "4. View Account Details\n"\
                           "0. Quit Program\n"\
                           "Choice: "))
        while choice < 0 or choice > 4:
            choice = int(input("Invalid Menu Choice.\n"\
                               "Reenter Choice: "))
    
        return choice
    
    #Logs user in to existing account      
    def logIn(accDct):
        os.system('cls')
        user = Account.Account("","","","",0,0)
        username = str(input("Enter Username(case sensitive): "))
        if username not in accDct:
            print("Account does not exist")
            os.system("pause")
            return user
    
        temp = Account.Account("","","","",0,0)
        temp = accDct[username]
    
        password = str(input("Enter Password(case sensitive): "))
        if password != temp.get_password():
            print("Incorrect password.")
            os.system("pause")
            return user
    
        user = accDct[username]
        return user
    
    
    #Creates a new account and a new account file if one doesn't exist
    def createAcc(accDct):
        os.system('cls')
        print("Enter account info:")
        username = str(input("UserName: "))
    
        if username in accDct:
            print("Account already exists.")
            os.system("pause")
            return
    
        password = str(input("Password: "))
        name = str(input("Name: "))
        email = str(input("Email: "))
        wins = 0
        loss = 0
    
        tempuser = Account.Account(username, password, name, email, wins, loss)
    
        accDct[username] = tempuser
    
        print("Account created.")
        os.system("pause")
    
    def viewAcc(user):
        os.system('cls')
    
    
    
        print("Account Details: ")
        print("Username: ",user.get_username())
        print("Name: ",user.get_name())
        print("Email: ",user.get_email())
        print("Wins: ",user.get_win())
        print("Losses: ",user.get_loss())
    
        os.system("pause")
    
    
    
    
    
    
    #Saves accounts dictionary to file
    def saveAcc(accDct):    
        oFile = open("userAccounts.txt", "wb")
    
        pickle.dump(accDct, oFile)
    
        oFile.close()
    
    
    main()
    

Any help is greatly appreciated.


Answer: Your play() function doesn't have a `return` statement, which means it's
returning `None` as its return value. That's how you're getting `None` into
your `user` variable in main(). Add a `return` statement to your play()
function and you should be fine.

