You don't need to reference the class inside itself, using bar instead of Test.bar will work fine.

class Test:
    @staticmethod
    def bar():
        pass

    FOO_DICT = {1: bar}


# You can access this outside of the class by simply using Test.FOO_DICT
print(Test.FOO_DICT)

However, there are cases where you really need to use a class in itself. For example

class Test:
    @staticmethod
    def bar():
        pass

    def test_with_other_of_same_instance(self, other: Test):
        print(other.FOO_DICT)

    FOO_DICT = {1: bar}

In this case,

  • I want to define a method that accepts an object of the same Test class.
  • I want to use python's type hinting to indicate that the expected argument is an instance of Test. This allows me get editor support and also so tools like pylance and mypy can notify me of possible errors if I passed a argument of wrong data type.

As at the time of this writing, I'll get a NameError: name 'Test' is not defined.

This is because by default I can't use a class within itself (It is possible later versions of python will change its default behavior, hence we won't be needing the solution below by that time).

But if you use Python versions from 3.7+ and you can't reference a class within itself, the simple solution came with PEP 563 - Postponed evaluation of annotations. It is implemented by adding a little line of code at the first line of the file

from __future__ import annotations
# other imports or code come afterwards


class Test:
    @staticmethod
    def bar():
        pass

    def test_with_other_of_same_instance(self, other: Test):
        print(other.FOO_DICT)

    FOO_DICT = {1: bar}

So you can use a class within itself in python by simply including that line at the beginning of the file.

Normally, if you use pylance or any similar tool, you get a warning or error display to show you that you imported something and didn't use it. But not in the case of annotations. You don't have to worry about any warning from your editor.

Note that this must occur at the beginning of the file otherwise you get a SyntaxError and versions earlier than 3.7 won't support this.

Answer from Victory Ifebhor on Stack Overflow
Top answer
1 of 3
19

You don't need to reference the class inside itself, using bar instead of Test.bar will work fine.

class Test:
    @staticmethod
    def bar():
        pass

    FOO_DICT = {1: bar}


# You can access this outside of the class by simply using Test.FOO_DICT
print(Test.FOO_DICT)

However, there are cases where you really need to use a class in itself. For example

class Test:
    @staticmethod
    def bar():
        pass

    def test_with_other_of_same_instance(self, other: Test):
        print(other.FOO_DICT)

    FOO_DICT = {1: bar}

In this case,

  • I want to define a method that accepts an object of the same Test class.
  • I want to use python's type hinting to indicate that the expected argument is an instance of Test. This allows me get editor support and also so tools like pylance and mypy can notify me of possible errors if I passed a argument of wrong data type.

As at the time of this writing, I'll get a NameError: name 'Test' is not defined.

This is because by default I can't use a class within itself (It is possible later versions of python will change its default behavior, hence we won't be needing the solution below by that time).

But if you use Python versions from 3.7+ and you can't reference a class within itself, the simple solution came with PEP 563 - Postponed evaluation of annotations. It is implemented by adding a little line of code at the first line of the file

from __future__ import annotations
# other imports or code come afterwards


class Test:
    @staticmethod
    def bar():
        pass

    def test_with_other_of_same_instance(self, other: Test):
        print(other.FOO_DICT)

    FOO_DICT = {1: bar}

So you can use a class within itself in python by simply including that line at the beginning of the file.

Normally, if you use pylance or any similar tool, you get a warning or error display to show you that you imported something and didn't use it. But not in the case of annotations. You don't have to worry about any warning from your editor.

Note that this must occur at the beginning of the file otherwise you get a SyntaxError and versions earlier than 3.7 won't support this.

2 of 3
5

If you want the dictionary to be in the class: define the function first and remove Test:

class Test:
    @staticmethod
    def bar():
         pass

    FOO_DICT = {1: bar}
Top answer
1 of 7
23

Update

In Python 3.11 the module is named typing instead of typing_extensions

from typing import Self


class Node:
    """Binary tree node."""

    def __init__(self, left: Self, right: Self):
        self.left = left
        self.right = right

This might be helpful:

from typing_extensions import Self


class Node:
    """Binary tree node."""

    def __init__(self, left: Self, right: Self):
        self.left = left
        self.right = right

typing_extensions offers a Self class to reference class itself which I think is most elegent way to self-reference(PEP 673).


As others have mentioned, you can also use string literals. But it comes to problem when you have multiple type hints.

# python 3.10
var: str | int

And then you write something like

class Node:
    def __init__(self, var: 'Node' | SomeClass):
        self.var = var

It will raise a TypeError: unsupported operand type(s) for |: 'str' and 'type'.

2 of 7
18

While this, as other answers have pointed out, is not a problem due to the dynamic typing, in fact, for Python3, this is a very real issue when it comes to type annotations. And this will not work (note a type annotation of the method argument):

class A:
    def do_something_with_other_instance_of_a(self, other: A):
        print(type(other).__name__)

instance = A()
other_instance = A()

instance.do_something_with_other_instance_of_a(other_instance)

results in:

   def do_something_with_other_instance_of_a(self, other: A):
   NameError: name 'A' is not defined

more on the nature of a problem here: https://www.python.org/dev/peps/pep-0484/#the-problem-of-forward-declarations

You can use string literals to avoid forward references

Other way is NOT using python3-style type annotation in such cases,

and this is the only way if you have to keep your code compatible with earlier versions of Python.

Instead, for the sake of getting autocompletion in my IDE (PyCharm), you can docstrings like this:

Update: alternatively, instead of using docstrings, you can use "type: " annotations in a comment. This will also ensure that mypy static type checking will work (mypy doesn't seem to care about docstrings):

Discussions

python - How to refer to the class from within it (like a recursive function) - Stack Overflow
The metaclass of A in your example ... or python3) 2010-01-09T23:55:20.533Z+00:00 ... While this is the solution to most practical problems, it is technically not the class body, but the method body, which matters at import time. 2020-07-19T12:26:15.027Z+00:00 ... This question is not about instances. It is about the class itself. 2022-09-02T06:08:17.513Z+00:00 ... Is there a way to refer to class A ... More on stackoverflow.com
🌐 stackoverflow.com
Type of the same class inside the class
There was an error while loading. Please reload this page · I have a method that returns itself but it doesn't know the type of the class inside More on github.com
🌐 github.com
3
July 5, 2017
python - What is the best way for a class to reference itself in a class attribute? - Stack Overflow
Unfortunately, in Python, a class attribute cannot reference its class name. The following raises a NameError: class Foo(object): bar = Foo In a situation where a class attribute must referenc... More on stackoverflow.com
🌐 stackoverflow.com
How does “self” in a class work?
What made the concept of self click for me, and this is completely ridiculous so you very well may get no miles out of this, but I treat building a class like building a Frankenstein monster. Attributes are physical features, methods are actions the monster can take, but "self" is what makes the monster alive, and thus self is the monster's (object's) "soul". That is, self is what made that particular monster (object) unique amongst other similar monsters (objects). I want to attack the village that is being mean about my sick experiments, and to really put a point on my powers, I also want to kidnap a villager. You know, evil scientist things. Since each monster has a soul, they can do independent things since the soul (self) makes them unique. Class Monster: def __init__(soul, name): soul.name = name def attack_village(): def kidnap_villager(): Now we "give life" to the monsters my instantiating (putting them on the table that lightning hits) two unique instances of the class: pat = Monster(pat) cris = Monster(cris) Despite being the "same" monster (same features, same look, same actions they can take), Pat and Cris can do things independently of the other. So I send Pat to kidnap a villager, and Cris to attack the village. pat.kidnap_villager() cris.attack_village() TL;DR: "self" is what makes each instance of a Class object unique. More on reddit.com
🌐 r/learnpython
70
262
December 22, 2021
🌐
YouTube
youtube.com › watch
Unlocking the Power of Self: How to Reference a Class Inside Itself in Python - YouTube
Discover how to refer to a class inside itself in Python by using `self`, and learn how to easily manage instances within a dictionary for better organizatio...
Published: September 20, 2025
Views: 2
🌐
DataCamp
campus.datacamp.com › courses › web-scraping-with-python › spiders
Self Referencing is Classy | Python
# Import scrapy library import scrapy # Create the spider class class YourSpider( ____ ): name = "your_spider" # start_requests method def start_requests( self ): self.print_msg( ____ ) # parse method def parse( self, response ): pass # print_msg method def print_msg( self, msg ): print( "Calling start_requests in YourSpider prints out:", msg ) # Inspect Your Class inspect_class( YourSpider )
🌐
GitHub
github.com › python › mypy › issues › 3661
Type of the same class inside the class · Issue #3661 · python/mypy
July 5, 2017 - I have a method that returns itself but it doesn't know the type of the class inside class TcpFlow(object): def __init__(self) -> None: self.matches = [] # type: List[str] def __enter__(self) -> TcpFlow: return self I got this error Trac...
Author: python
Find elsewhere
🌐
w3tutorials
w3tutorials.net › blog › self-referencing-class-definition-in-python
Self-Referencing Class Definition in Python: How to Reference the Class Name Within Its Declaration — w3tutorials.net
Cons: Only works for annotations (not for class-level variables like CONFIG), requires Python 3.7+. What it is: Metaclasses are "classes of classes"—they control how class objects are created. Since metaclasses run after the class body executes, they can inject references to the class into its namespace. A metaclass’s __new__ or __init__ method runs after the class body is executed, so the class object already exists. We can use this to add attributes that reference the class itself.
🌐
Reddit
reddit.com › r/learnpython › how does “self” in a class work?
r/learnpython on Reddit: How does “self” in a class work?
December 22, 2021 -

You have to add “self” as an argument to a class method. Why this specific syntax and how does it get interpreted? Is this because it inherits from the Python object model?

Is there any language where public methods do not contain “self” as an argument?

Thank you

🌐
Medium
grzegorz-makowski.medium.com › understanding-self-and-cls-in-python-b674f5e5951d
Understanding self and cls in Python | by Grzegorz Makowski | Medium
January 21, 2021 - However, if this function wouldn’t be decorated with @classmethod, the first parameter passed to this function would be the object itself, not its class. We should be careful when using data classes. You should always think about how you will use variables defined inside a class. I would rather use instance variables instead of class variables unless I had good reason to do otherwise. One “rule” that You should keep in mind is: “Always access class instance variables by class reference (<class_name>.<variable_name>) or via the @classmethod decorator rather than by object reference”.
🌐
Python.org
discuss.python.org › typing
Using `Self` with classmethod and a `Self` class attribute - Typing - Discussions on Python.org
June 16, 2024 - Hello, I’m trying to type the following code, where a class has a class attribute containing a reference to itself (something like a Singleton for instance). It would look like this: from typing import Self class MyClass: _singleton: Self | None = None @classmethod def new(cls) -> Self: if cls._singleton is None: cls._singleton = cls() return cls._singleton The type checker complains with: Incompatible return value type (got "MyClass", expected "Se...
🌐
Stack Overflow
stackoverflow.com › questions › 58292893 › class-variable-reference-itself
python - Class variable reference itself? - Stack Overflow
@Joshuah: That particular item is something unique defined by the class so it can be referenced (and recognized as such) when doing the second part of the initialization in the derived class' __init__(). Since it's not used until after the class has been defined, it avoids the issue of trying to reference the instance before it has been created. Think of it as a "placeholder".. ... I think I understand what you are attempting to say, but I will have to run the code myself both with and without that particular line to grasp exactly what it is for. ... @Joshuah: Didn't know you were asking about a particular line. Because of how name look-ups work in Python inside a class, self.THIS is equivalent to WorldLocation.THIS in this usage case, so it's a reference to the class attribute.
🌐
CodingNomads
codingnomads.com › what-is-python-self
What is Python Self
Python class instances are `self`-aware! When you reference `self` within a class definition, it means that you're referencing the instance object itself.
🌐
Python.org
discuss.python.org › python help
Access class object in class body - Python Help - Discussions on Python.org
June 24, 2024 - this is a contrived example, but only because I’m tring to semplify it… Is there a way for a function invoked in a class body to access the class itself? let me show you: def my_deco(fun): ... return fun class MyClass: @my_deco @classmethod def my_method(cls): ... in this example I have my_deco that is invoked during the building of MyClass, and receive an instance of classmethod (that I’ve just discovered it’s a type!)
🌐
Real Python
realpython.com › python-type-self
Python's Self Type: How to Annotate Methods That Return self – Real Python
July 3, 2026 - In this tutorial, you'll learn how to use the Self type hint in Python to annotate methods that return an instance of their own class. You'll gain hands-on experience with type hints and annotations of methods that return an instance of their class, making your code more readable and maintainable.