blog banner for post titled: How to Solve Guide for Python AttributeError

We raise a Python AttributeError when we try to call or access an attribute of an object that does not exist for that object.

This tutorial will go through what an attribute is, what the AttributeError is in detail, and we will go through four examples to learn how to solve the error.

What is a Python AttributeError?

An attribute of an object is a value or a function associated with that object. We can express calling a method of a class as referencing an attribute of a class.

Let’s look at an example of a Python class for the particle electron

class Electron:
    def __init__(self):
        self.charge = -1
        self.mass = 0.51
        self.spin = 1/2
 
    def positron(self):
        self.charge = +1
        return self.charge

We can think of an attribute in Python as a physical attribute of an object. In this example, the fundamental particle, the electron, has physical attributes of charge, mass, and spin. The Electron class has the attributes charge, mass, and spin.

An attribute can also be a function. The function positron() returns the charge of the electron’s anti-particle, the positron.

Data types can have attributes. For example, the built-in data type List has the append() method to append elements to an existing list. Therefore, List objects support the append() method. Let’s look at an example of appending to a list:

a_list = [2, 4, 6]

a_list.append(8)

print(a_list)

Attributes have to exist for a class object or a data type for you to reference it. If the attribute is not associated with a class object or data type, you will raise an AttributeError.

Example #1: Trying to Use append() on a String

Let’s look at an example scenario where we concatenate two strings by appending one string to another.

string1 = "research"

string2 = "scientist"

string1.append(string2)

Using append() is impossible because the string data type does not have the append() method. Let’s run the code to see what happens:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
1 string1.append(string2)

AttributeError: 'str' object has no attribute 'append'

Solution

To solve this problem, we need to define a third string. We can then concatenate the two strings using the + symbol and assign the result to the third string. We can concatenate a space between the two strings so that the words do not run together. Let’s look at how the revised code:

string1 = "research"

string2 = "scientist"

string3 = string1 + " " + string2

print(string3)
research scientist

Example #2: Trying to Access an Attribute of a Class that does not exist

Let’s look at an example scenario where we want to access an attribute of a class that does not exist. We can try to create an instance of the class Electron from earlier in the tutorial. Once we have the instance, we can try to use the function get_mass() to print the mass of the electron in MeV.

class Electron:

   def __init__(self):

       self.charge = -1

       self.mass = 0.51

       self.spin = 1/2
  
   def positron(self):

       self.charge = +1

       return self.charge

electron = Electron()

mass = electron.get_mass()

If we try to run the code, we get the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
1 mass = electron.get_mass()

AttributeError: 'Electron' object has no attribute 'get_mass'

The Electron class has no attribute called get_mass(). Therefore we raise an AttributeError.

Solution

To solve this, we can do two things. We can add the method to the class and use a try-except statement. First, let’s look at adding the method:

class Electron:
    def __init__(self):
        self.charge = -1
        self.mass = 0.51
        self.spin = 1/2

    def positron(self):
        self.charge = +1
        return self.charge

    def get_mass(self):
            return self.mass
electron = Electron()

mass = electron.get_mass()

print(f' The mass of the electron is {mass} MeV')

 The mass of the electron is 0.51 MeV

Secondly, let’s look at using try-except to catch the AttributeError. We can use try-except statements to catch any error, not just AttributeError. Suppose we want to use a method called get_charge() to get the charge of the electron object, but we are not sure whether the Electron class contains the get_charge() attribute. We can enclose the call to get_charge() in a try-except statement.

class Electron:

    def __init__(self):

        self.charge = -1

        self.mass = 0.51

        self.spin = 1/2

    def positron(self):

        self.charge = +1

        return self.charge

    def get_mass(self):

            return self.mass

electron = Electron()

try:

    charge = electron.get_charge()

except Exception as e:

    print(e)
'Electron' object has no attribute 'get_charge'

Using try-except statements aligns with professional development and makes your programs less prone to crashing.

Example #3: NoneType Object has no Attribute

NoneType means that whatever class or object you are trying to access is None. Therefore, whenever you try to do a function call or an assignment for that object, it will raise the AttributeError: ‘NoneType’ object has no attribute. Let’s look at an example scenario for a specific NoneType attribute error. We will write a program that uses regular expressions to search for an upper case “S” character at the beginning and print the word. We need to import the module re for regular expression matching.

import re

# Search for an upper case "S" character in the beginning of a word then print the word

string = "Research Scientist"

for i in string.split():

    x = re.match(r"\bS\w+", i)

    print(x.group())

Let’s run the code and see what happens:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
      1 for i in string.split():
      2     x = re.match(r"\bS\w+", i)
      3     print(x.group())
      4 

AttributeError: 'NoneType' object has no attribute 'group'

We raise the AttributeError because there is no match in the first iteration. Therefore x returns None. The attribute group() does not belong to NoneType objects.

Solution

To solve this error, we want to only call group() for the situation where there is a match to the regular expression. We can therefore use the try-except block to handle the AttributeError. We can use continue to skip when x returns None in the for loop. Let’s look at the revised code.

import re

# Search for an upper case "S" character in the beginning of a word then print the word

string = "Research Scientist"
for i in string.split():
    x = re.match(r"\bS\w+", i)
    try:
        print(x.group())
    except AttributeError:
        continue
Scientist

We can see that the code prints out Scientist, which is the word that has an upper case “S” character.

Example #4: Handling Modules

We can encounter an AttributeError while working with modules because we may call a function that does not exist for a module. Let’s look at an example of importing the math module and calling a function to perform a square root.

import math

number = 9

square_root_number = math.square_root(number)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
1 square_root_number = math.square_root(number)

AttributeError: module 'math' has no attribute 'square_root'

The module math does not contain the attribute square_root. Therefore we get an AttributeError.

Solution

To solve this error, you can use the help() function to get the module’s documentation, including the functions that belong to the module. We can use the help function on the math module to see which function corresponds to the square root.

import math

help(math)
  sqrt(x, /)

        Return the square root of x.

The function’s name to return the square root of a number is sqrt(). We can use this function in place of the incorrect function name.

square_root_number = math.sqrt(number)

print(square_root_number)
3.0

The code successfully returns the square root of 9. You can also use help() on classes defined in your program. Let’s look at the example of using help() on the Electron class.

help(Electron)

class Electron(builtins.object)
 |  Methods defined here:
 |  
 |  __init__(self)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  get_mass(self)
 |  
 |  positron(self)

The help() function returns the methods defined for the Electron class.

Summary

Congratulations on reading to the end of this tutorial. Attribute errors occur in Python when you try to reference an invalid attribute.

  • If the attribute you want for built-in data types does not exist, you should look for an attribute that does something similar. For example, there is no append() method for strings but you can use concatenation to combine strings.
  • For classes that are defined in your code, you can use help() to find out if an attribute exists before trying to reference it. If it does not exist you can add it to your class and then create a new instance of the class.
  • If you are not sure if a function or value does not exist or if a code block may return a NoneType object, you can wrap the code in a try-except statement. Using a try-except stops your program from crashing if you raise an AttributeError.

For further reading on AttributeError, you can go to the following article: How to Solve Python AttributeError: ‘list’ object has no attribute ‘split’

Go to the online courses page on Python to learn more about Python for data science and machine learning.

Have fun and happy researching!