How to fix NameError: name 'self' is not defined

When working with Python classes and objects, you might encounter the following error:

NameError: name 'self' is not defined

This error occurs because Python can’t find the definition of the self variable that you called in your code.

There are two possible scenarios that cause this error:

  1. You use self as the default value for an argument
  2. You access self from a static method

This tutorial will show you how to fix the error in each scenario.

1. Using self as the default value for an argument

Suppose you have a class named Person with the following definition:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

Next, you created a method named greet() inside the class defined as follows:

def greet(self, name=self.name):
    print(f'Hello! My name is {name}')

After that, you created an instance of the class and called the greet() method:

joe = Person('Joe', 22)
joe.greet()

You’ll get the following error:

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    class Person:
  File "main.py", line 6, in Person
    def greet(self, name = self.name):
                           ^^^^
NameError: name 'self' is not defined

This error occurs because the self.name attribute is used as the default argument for the name parameter.

In Python, default arguments are evaluated when Python runs the code for the first time. That is, when Python put your method definition in the memory and makes it available for calling.

But the self object is only available when the method is actually called. This is why you can’t use self as a default argument.

To resolve this error, you need to assign self to the parameter in your method body. A common pattern is to use None as the default argument, and change it inside the function as follows:

def greet(self, name=None):
    if name is None:
        name = self.name
    print(f'Hello! My name is {name}')

Now you can run the greet() function without receiving the error:

joe = Person('Joe', 22)
joe.greet()  # Hello! My name is Joe

But the drawback of this solution is that you can’t explicitly set the name parameter to None because it will just get reassigned to self.name.

If you have many parameters that use self attributes as the default arguments, then you need to create many if statements as shown above.

It looks ugly and inconvenient, but there’s no other way considering how Python evaluates the default arguments.

2. You access self from a static method

As you probably know, Python implicitly passed the self object as the first argument anytime you called a class method.

A static method is an exception to this rule because it was intended to work with class attributes instead of class instances.

Suppose you create a Person class with a static method called greet() as shown below:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @staticmethod
    def greet():
        print(f'Hello! My name is {self.name}')

Next, you create a new instance of the class and call the greet() method as follows:

joe = Person('Joe', 22)
joe.greet()

Output:

Traceback (most recent call last):
  File "main.py", line 11, in <module>
    joe.greet()
  File "main.py", line 8, in greet
    print(f'Hello! My name is {self.name}')
                               ^^^^
NameError: name 'self' is not defined

When you declared a method as static in Python, the self object is not passed implicitly, so the error occurs.

To resolve this error, you need to remove the @staticmethod modifier above the method name and define the self object as a parameter of the method:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greet(self):
        print(f'Hello! My name is {self.name}')

Now you can access self inside the greet() method without receiving the error.

Conclusion

The NameError: name 'self' is not defined occurs in Python when you try to access the self object from a place that doesn’t have the definition of self.

The most probable cause for this error is that you use the self attribute as the default argument of your method’s parameter, or you try to access self from a static method.

Keep in mind that this error doesn’t appear when you didn’t specify self as the first parameter of a method.

For that, you’ll get another error saying TypeError: method takes 0 positional arguments but 1 was given.

I hope this tutorial is helpful. Happy coding! 👍

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.