1
class myclass(object):
    i=0
    def increase(self):
        self.i+=1
        print('increased value:', self.i)

if __name__=='__main__':
    m=myclass()
    m.increase()

Here is a class variable and self.i is instance variable , on executing i get o/P as 1.

But if comment class variable i I get an error

self.i+=1
AttributeError: 'myclass' object has no attribute 'i'

what is the relation between class variable i and instance variable self.i here.

4 Answers 4

1

What happens is that you are shadowing the class variable with a member variable.

See what happens when you instanciate another myclass-object and add a few printouts to your code:

class myclass(object):
    i=0
    def increase(self):
        myclass.i+=1
        print('incresed value:',self.i)

if __name__=='__main__':
    m=myclass()
    n=myclass()
    print("m.i=", m.i)
    print("n.i=", n.i)
    m.increase()
    print("m.i=", m.i)
    print("n.i=", n.i)

The output is now:

m.i= 0
n.i= 0
incresed value: 1
m.i= 1
n.i= 0

You see that you incremented the value of the i-member of m, but not of n. This is because self (like this in c++) always refers to the current object instance. If you update your code to the following, you are actually incrementing the class variable:

def increase(self):
    myclass.i+=1
    print('incresed value:',self.i)

And the output changes to the following:

m.i= 0
n.i= 0
incresed value: 1
m.i= 1
n.i= 1

Like Guillaume Jacquenot already stated in his answer, if you'd like to use member variables, it is advisable to initialize them in __init__(). In your case, the interpreter ist just using the class variable with the same name when it can't find a member variable, and in the same line initializing a member variable (with identical name i). If you comment out the class variable, you're trying to increment a variable which does not exist yet, hence the interpreter error.

Sign up to request clarification or add additional context in comments.

Comments

0

A class variable is a variable which can be changed by all instances of your class. You call it by [class_name].[variable_name]

For Example:

class myclass(object):
    i=0
    def increase(self):
        myclass.i+=1
        print('incresed value:',self.i)

if __name__=='__main__':
    m=myclass()
    k = myclass()

    k.increase()
    m.increase()
    m.increase()
    m.increase()
    m.increase()
    k.increase()

results in

incresed value: 1
incresed value: 2
incresed value: 3
incresed value: 4
incresed value: 5
incresed value: 6

An instance variable on the other hand (like you have it) can only be accessed by the instance which created it (with self.[variable_name]). To access a variable, the variable first needs to be instantiated. Like

a+=5

would create an error while

a = 0
a+= 5 

would not

In your example the instance variable is not specificly instantiated. But because of the class variable (i=0) python automatically instantiates the instance variable (i) with the value of the class variable. (because class and instance variable have the same name)

In other words:

When in your example the class variable i=0 is removed python does not know what value your instance variable self.i should have in the beginning.

Comments

0

You use the following statements to declare a constant inside your class. i is not supposed to be modified later.

class myclass(object):
     i=0

You can access it with

 value = myclass().i

If you want a counter, you declare it in the constructor __init__, and increase it in a method

class myclass(object):
    def __init__(self): 
        self.counter = 0
    def increase(self): 
        self.counter += 1

Comments

0

The problem you are facing is the lack of definition of i object after you remove the class variable. The i=0 statement is the only definition. It is the same with any other variable, nothing special happens here:

i+=1

yields the same error if you put it in main or anywhere. In order to do the increment += you need to have the object declared first.

You can do:

class myclass(object):
def increase(self):
    self.i=0
    self.i+=1
    print('increased value:', self.i)

which makes no sense, but illustrates the issue, i think.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.