NameError: name 'rank' is not defined even though i have mentioned it in global

Question:

The code below is a simplified version of a bigger code. The main action i want to perform is to use and change rank and progress inside the inc_progress(self) function.

class User:
    rank=-8
    progress=0
    def inc_progress(self):
        global rank, progress
        rank+=1
        print(rank,progress)



u=User()
u.inc_progress()

but it gives me the error: NameError: name 'rank' is not defined. Did you mean: 'range'?

does anyone know a possible fix for this issue, so that I can use and change the values of rank and progress in the inc_progress(self) function

Asked By: Rolling Happy

||

Answers:

By defining rank and progress outside of __init__, you’ve defined them as class variables, meaning that they belong to the class and will be available to all instances of that class. https://pynative.com/python-class-variables/

Here’s a modified version of your code that does what you’re expecting (and probably some things that you aren’t!)

class User:
rank=-8
progress=0
def inc_progress(self):
    User.rank+=1
    print(User.rank, User.progress)

u=User()
u.inc_progress() # Output: -7, 0

Ok great! Problem solved, right? Well, maybe. Look at this.

u=User()
u.inc_progress() # Output: -7, 0
u2 = User()
print(u2.rank, u2.progress) # Output: -7, 0

Wait, what? That newly created instance of User has rank=-7 instead of -8! That’s class variables for you. If you want rank and progress to be specific to the instance, then define them during initialization and access them as usual with self

class User:
def __init__(self):
    self.rank=-8
    self.progress=0
def inc_progress(self):
    self.rank+=1
    print(self.rank, self.progress)

u=User()
u.inc_progress() # Output: -7, 0
u2 = User()
print(u2.rank, u2.progress) # Output: -8, 0
Answered By: picobit
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.