0

I want to learn basics of classes in Python and got stuck. I declared same name of class variables and instance variable so that I could understand difference better but when I am using class variable inside the class methods it is showing error like NameError: global name 'a' is not defined. Can someone please tell me how to declare class variable inside and outside the class if both class variables and instance variables have same name. Code is given below and so error in output

class abc:
    a=10
    def __init__(self,a):
        self.a=a
    def mod1(self):
        global a
        a=5
        self.a=105
    def mod2(self):
        a=15
        self.a=110
    def read(self):
        print(self.a)
        print(a)

b=abc(20)
print(b.a)
b.read()
b.mod1()
b.read()
b.mod2()
b.read()

Error is

20
20
Traceback (most recent call last):
  File "/Users/rituagrawal/PycharmProjects/untitled2/code/garbage.py", line 18, in <module>
    b.read()
  File "/Users/rituagrawal/PycharmProjects/untitled2/code/garbage.py", line 14, in read
    print(a)
NameError: global name 'a' is not defined

Process finished with exit code 1
ritz
  • 39
  • 4

3 Answers3

1

Attributes set at the class level are shared by every instance of the class.

Attributes set on the instance in __init__ or other methods - for example self.a = a - are different for every instance, and available in every method.

References can also be set within a method - a = 15 - and these are only in scope within the method. print(a) within your read() method fails because no a has been set in that method.

Update:

Some code to illustrate.

class MyClass:
    a = 10

    def __init__(self, b):
        self.b = b

    def read(self):
        c = 99

        print(self.a) # Class attribute - the same for all instances of MyClass
        print(self.b) # Instance attribute - each instance of MyClass has it's own, available in all methods
        print(c) # Local - only available in this method.
brunns
  • 2,689
  • 1
  • 13
  • 24
0

Welcome to SO Ritu Agrawal.

self.a 

is an instance variable, as you seem to have surmized. If you want to refer to the static (class) variable a, then you should use:

abc.a

So:

class abc:
    a=10
    def __init__(self,a):
        self.a=a
        abc.a = 40

b=abc(20)
print(b.a)
print(abc.a)

You can also use the __class__ member of an instance, so:

class abc:
    a=10
    def __init__(self,a):
        self.a=a
        __class__.a = 40

b=abc(20)
print(b.a)
print(b.__class__.a)
Mario Camilleri
  • 1,457
  • 11
  • 24
  • Thanks for your reply. can you please elaborate which one of "a" is changing if I am declaring abc.a=40 because output of this program is 20,40 and I am still left confused which variable is changing class variable or instance variable if I am using abc.a=40 – ritz Apr 17 '19 at 08:20
  • Since abc is the class, abc.a = 40 changes the class variable to 40. Since b is an instance, b.a=50 changes the instance variable to 50. – Mario Camilleri Apr 17 '19 at 16:15
0

To begin with, I simplified your class as follows. Here a, the class variable, is referenced inside the class functions using abc.a. The a which is the instance variable is referenced using self.a

class abc:

    a=5

    def __init__(self,a):
        self.a=a

    def set(self, class_a, instance_a):

        abc.a=class_a
        self.a=instance_a

    def read(self):

        print(abc.a)
        print(self.a)

Then, we start by defining the class and trying to read both variables. Class variable is still 5, and instance variable is 20

b=abc(20)
b.read()
#5
#20

Then, I set both class and instance variable a and try to read them. Class variable is changed to 30, and instance variable is changed to 60

b.set(30, 60)
b.read()
#30
#60

We can also directly access both variables outside the class using instance_object.a for instance variable and ClassName.a for class variable.

print(b.a)
#30
print(abc.a)
#60
Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40