"Local variable referenced before assignment " appears when putting code into function

1.4k Views Asked by At

My code works fine until I try putting it into a function. Once I define the function, indent the code, and call the function, I get the error message:

"Local variable 'print' referenced before assignment.

Why is that popping up when all I'm changing is putting it into a function? I never assign a variable 'print.' Please help!
I blocked out the token to access the server I am trying to reach for security.

    def printSet():
        for user in range (0,len(parsed_json['members'])-1):
            userDict=parsed_json['members'][user]#Catches errors resulting from users not having all settings configured
            try:
                print("id: "+userDict["id"])
            except KeyError:
                print("No ID found")
            try:
                print("team id: "+userDict["team_id"])
            except KeyError:
                print("No team ID found")
            try:
                print("name: "+userDict["name"])
            except KeyError:
                print("No name found")
            try:
                print("real name: "+userDict["real_name"])
            except KeyError:
                print("No real name found")
            userProf=userDict['profile']
            try:
                print("title: "+userProf["title"])
            except KeyError:
                print("No title found")
            try:
                print("real name: "+userProf["real_name"])
            except KeyError:
                print("No real name found")
            try:
                print("real name normalized: "+userProf["real_name_normalized"])
            except KeyError:
                print("No real name normalized found")
            try:
                print("display name: "+userProf["display_name"])
            except KeyError:
                print("No display name found")
            try:
                print("display name normalized: "+userProf["display_name_normalized"])
            except KeyError:
                 print("No display name normalized found")
            try:
                print("email: "+userProf["email"])
            except KeyError:
                print:("No email found")
            try:
                print("first name: "+userProf["first_name"])
            except KeyError:
                print("No first name found")
            try:
                print("last name: "+userProf["last_name"])
            except KeyError:
                print("No last name found")
    #To easily show when one member ends and another begins
            print("----------------------------------")
    printSet()
2

There are 2 best solutions below

0
On BEST ANSWER

I never assign a variable 'print.'

Yes you do:

print:("No email found")

This is an annotated assignment statement, which annotates print with type "No email found", but assigns no value.

An annotated assignment always creates a local variable, even if you aren't assigning a value. From the docs:

If a name is annotated in a function scope, then this name is local for that scope.

In case you're wondering, empty annotated assignments are useful for cases like this:

n: int
if spam:
    n = spam**2
else:
    n = -1

This is the only way you could tell a static type checker like Mypy to verify that n ends up holding an int no matter which if branch you take.

8
On

"I assign parsed_json elsewhere in my code"

Well that's the issue. You have to pass the variable to the code, or declare it global, but best to avoid this. You could make the simple change like so.

def printSet(parsed_json):
    for user in range (0,len(parsed_json['members'])-1):
       userDict=parsed_json['members'][user]
    #####do a bunch of stuff or whatever

printSet(parsed_json)

Note that you would need to do this for each variable you use in your function

Something else to simplify you code and help debug would be getting rid of all the try-excepts

keylist=["id", "real_name", ..... "last_name"] #not required, but helpful if you want to print "not found" type messages
for k in keylist:
    if k in userDict.keys():
        print('{}: {}'.format(k, userDict[k]))
    else:
        print('No {} found'.format(k))