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
🌐
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
🌐
DataCamp
campus.datacamp.com › courses › web-scraping-with-python › spiders
Self Referencing is Classy | Python
That is, if we want to refer to the method parse within the start_requests method, we would need to write self.parse rather than just parse; what writing self does is tell the code: "Look in the same class as start_requests for a method called parse to use."
Find elsewhere
🌐
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”.
🌐
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.
🌐
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...
🌐
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!)
🌐
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.
Top answer
1 of 2
4

Karl's answer is entirely right about everything, but there is certainly a way to make resize act as you're expecting.

Three steps:

  1. Make a copy of the tree
  2. Re-initialize the tree so it's the next size larger
  3. Set the enlarged tree's left to the copy of the original tree

    def resize(self,n):
            while self.size < n:
                new = self.copy()
                self.__init__(int(round(self.size, 2)) * 2)
                self.left = new
    
            print("size in resize",self.size)
    
    def copy(self):
            new = tree(1)
            new.left = self.left
            new.right = self.right
            new.size = self.size
            new.free = self.free
            return new
    

Basically, you were trying to do it backwards -- replace self and reuse self for self.left, instead of replacing self.left and reusing self.

2 of 2
2

self = t

This does not, and cannot be rewritten to, do what you want. There is nothing "special" about the name self in Python; it's just like any other variable (the fact that you have to pass it explicitly to methods should have been your first hint, unlike in languages that treat this as a keyword, should have been your first hint ;) ), and like all other variables, it has reference semantics.

self = t means "from this point onward (until another re-definition or the end of scope), self no longer refers to what that self parameter referred to, but instead to the value that t refers to".

Also, you have a typo in one case of your __init__ method ('rigt'), and I assume that the number of free nodes is supposed to be an invariant something like size - occupied; in which case it would be cleaner to count the occupied nodes and use a method or property to calculate the free ones, instead of trying to update that count on every modification.

(Moreover, what you seem to be trying to do is all kinds of un-Pythonic. In particular, the idea of a container having a specific "allocated size" is strange; that sort of thing normally only matters on the C side of the fence. What do you need a binary tree for? Also, this method isn't going to balance the tree at all. And what use is a tree if none of the nodes store any data?)

🌐
Sololearn
sololearn.com › en › Discuss › 1931779 › python-nested-class-and-also-a-main-class-itself
Python nested class and also a main class itself?
August 15, 2019 - Sololearn is the world's largest community of people learning to code. With over 25 programming courses, choose from thousands of topics to learn how to code, brush up your programming knowledge, upskill your technical ability, or stay informed about the latest trends.