Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why method can't access class variable?

Tags:

python

I am trying to understand variable scopes in Python, most of the things are clear to me except for the part that I don't understand why class variable is not accessible from its method.
In following example mydef1() can't access a, but if a is declared in global scope(outside class definition) it can.

class MyClass1:
    a = 25
    def mydef1(self):
        print(a)
ins1 = MyClass1()
ins1.mydef1()

Output

Traceback (most recent call last):
  File "E:\dev\Python\scope_test2.py", line 6, in <module>
    ins1.mydef1()
  File "E:\dev\Python\scope_test2.py", line 4, in mydef1
    print(a)
NameError: name 'a' is not defined
like image 954
Tejas Sarade Avatar asked Nov 15 '25 17:11

Tejas Sarade


1 Answers

It's important to understand that some of these comments are not equivalent. MyClass.a is a member of the class itself, self.a is a member of the instance of the class.

When you use self.a it will return a from the class, because there is no a on the instance. If there was also an a which was a member of the instance, it would return that instead. Generally the instance a is set using the __init__ constructor. Both of these can exist simultaneously.

class MyClass1:
    a = 25

    def __init__(self):
        self.a = 100

    def instance_a(self):
        print(self.a)

    def change_instance_a(self):
        self.a = 5

    def class_a(self):
        print(MyClass1.a)

    def change_class_a(self):
        MyClass1.a = 10


# Create two instances
ins1 = MyClass1()
ins2 = MyClass1()

# Both instances have the same Class member a, and the same instance member a
ins1.instance_a()
ins2.instance_a()
ins1.class_a()
ins2.class_a()

# Now lets change instance a on one of our instances
ins1.change_instance_a()

# Print again, see that class a values remain the same, but instance a has
# changed on one instance only
print()
ins1.instance_a()
ins2.instance_a()
ins1.class_a()
ins2.class_a()

# Lets change the class member a on just one instance
ins1.change_class_a()

# Both instances now report that new value for the class member a
print()
ins1.instance_a()
ins2.instance_a()
ins1.class_a()
ins2.class_a()
like image 197
dpwr Avatar answered Nov 18 '25 07:11

dpwr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!