Search code examples
pythonpython-3.xinstance-variablesattributeerror

"AttributeError" while accessing instance variables


Python is raising the below exception when running my script. Could somebody please explain why this is happening and how to fix it?

Traceback (most recent call last):
  File "C:\Users\vinsunny\AppData\Local\Programs\Python\Python36\test.py", line 28, in <module>
    test.my_func()
  File "C:\Users\vinsunny\AppData\Local\Programs\Python\Python36\test.py", line 23, in my_func
    print('non secret no. from test_func: ', self.number2)
AttributeError: 'Test' object has no attribute 'number2'"
class Test():

    __class_secret_number = 100

    def __secret_func(self):
        self.number1 = 1
        self.__secret_number1 = 11
        print('You cannot see this unless accessing from the Class itself')

    def test_func(self):
        self.number2 = 2
        self.__secret_number2 = 22

    def my_func(self):
        self.__secret_func()
        print('Secret no. from class: ', self.__class_secret_number)

        print('non secret no. from secret func: ', self.number1)
        print('Secret no. from secret func: ', self.__secret_number1)

        # These two prints raise an exception.
        print('non secret no. from test_func: ', self.number2)
        print('Secret no. from test_func: ', self.__secret_number2)

test = Test()
test.my_func()

Solution

  • At the time the offending print statement is executed, the number2 attribute on your Test instance has not been defined.

    The first time the number2 attribute gets set is in the test_func() method. i.e. Attempting to access number2 before calling test_func() will result in the error you are observing.

    You should assign a default value to self.number2 in the initializer for the Test class. You could also call test_func() before calling my_func(). But, either way, it's still good practice to initialize all instance attributes in Test.__init__.

    The interpreter will raise an exception for the same reason when you try to access the undefined attribute __secret_number_2 in my_func().