self.__class__ is a reference to the type of the current instance.

For instances of abstract1, that'd be the abstract1 class itself, which is what you don't want with an abstract class. Abstract classes are only meant to be subclassed, not to create instances directly:

>>> abstract1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated

For an instance of a subclass of abstract1, self.__class__ would be a reference to the specific subclass:

>>> class Foo(abstract1): pass
... 
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True

Throwing an exception here is like using an assert statement elsewhere in your code, it protects you from making silly mistakes.

Note that the pythonic way to test for the type of an instance is to use the type() function instead, together with an identity test with the is operator:

class abstract1(object):
    def __init__(self):
        if type(self) is abstract1: 
            raise NotImplementedError("Interfaces can't be instantiated")

type() should be preferred over self.__class__ because the latter can be shadowed by a class attribute.

There is little point in using an equality test here as for custom classes, __eq__ is basically implemented as an identity test anyway.

Python also includes a standard library to define abstract base classes, called abc. It lets you mark methods and properties as abstract and will refuse to create instances of any subclass that has not yet re-defined those names.

Answer from Martijn Pieters on Stack Overflow
Top answer
1 of 6
54

self.__class__ is a reference to the type of the current instance.

For instances of abstract1, that'd be the abstract1 class itself, which is what you don't want with an abstract class. Abstract classes are only meant to be subclassed, not to create instances directly:

>>> abstract1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated

For an instance of a subclass of abstract1, self.__class__ would be a reference to the specific subclass:

>>> class Foo(abstract1): pass
... 
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True

Throwing an exception here is like using an assert statement elsewhere in your code, it protects you from making silly mistakes.

Note that the pythonic way to test for the type of an instance is to use the type() function instead, together with an identity test with the is operator:

class abstract1(object):
    def __init__(self):
        if type(self) is abstract1: 
            raise NotImplementedError("Interfaces can't be instantiated")

type() should be preferred over self.__class__ because the latter can be shadowed by a class attribute.

There is little point in using an equality test here as for custom classes, __eq__ is basically implemented as an identity test anyway.

Python also includes a standard library to define abstract base classes, called abc. It lets you mark methods and properties as abstract and will refuse to create instances of any subclass that has not yet re-defined those names.

2 of 6
1

The code that you posted there is a no-op; self.__class__ == c1 is not part of a conditional so the boolean is evaluated but nothing is done with the result.

You could try to make an abstract base class that checks to see if self.__class__ is equal to the abstract class as opposed to a hypothetical child (via an if statement), in order to prevent the instantiation of the abstract base class itself due to developer mistake.

🌐
GeeksforGeeks
geeksforgeeks.org › python › self-in-python-class
self in Python class - GeeksforGeeks
January 23, 2026 - In Python, self is a fundamental concept when working with object-oriented programming (OOP). It represents the instance of the class being used. Whenever we create an object from a class, self refers to the current object instance.
🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.3 documentation
For instance, if you have a function that formats some data from a file object, you can define a class with methods read() and readline() that get the data from a string buffer instead, and pass it as an argument. Instance method objects have attributes, too: m.__self__ is the instance object with the method m(), and m.__func__ is the function object corresponding to the method.
🌐
SoloLearn
sololearn.com › pl › Discuss › 1550201 › what-exactly-does-self-parameter-do-in-python
What exactly does 'self' parameter do in Python? | Sololearn: Learn to code for FREE!
This is made with the first parameter (usually called self but its not mandatory) that give you the current (in execution context) instance of that class.
🌐
Reddit
reddit.com › r/learnpython › what is "self.__class__.instance = self" useful for?
r/learnpython on Reddit: What is "self.__class__.instance = self" useful for?
March 27, 2012 -

I'm looking at a class definition that includes this line in its constructor. Something like:

class someClass:
    def __init__(self):
        self.__class__.instance = self

Then other objects access the instance using:

someClass.instance

If I understand correctly, this adds an attribute called instance to the class object. The instance attribute will be created when the first instance of the class is created. If there is more than one instance, the instance attribute will always point to the last instance that was created. Is that right?

My main question is why is this useful? Is this a particularely elegant or pythonic way of giving other objects access to a class instance? In the case I'm looking at, it's a high level class that manages everything going on in the program. Lots of objects in the program need access to this class instance. Is this a good usecase for this approach?

Top answer
1 of 4
9
No, singletons are rarely a good idea in general, and this approach to enforcing the Singleton contract (not that this kind of "enforcement" is really Pythonic) is totally broken anyway. I can't say I've ever seen it recommended anywhere; it really looks like something that somebody made up while not really having a good grasp on the concept.
2 of 4
6
As others have noted, this is a (rather poor) attempt at creating a singleton class in Python. For example, what would happen if some idiot were to call __init__() in your codebase (which is really easy to do). I don't think they'd like what happens next! (For the record, this is what happens next, with this as input: class someClass: def __init__(self): self.data = 0 self.__class__.instance = self someClass() someClass.instance.data = 2 >>> import singleton >>> singleton.someClass.instance.data 2 >>> singleton.someClass() >>> singleton.someClass.instance.data 0 So now I have the ability to create multiple instances of someClass, and I've destroyed the one with potentially important information.) Whether you should be using a singleton in the first place is another question for another time (the odds are against it unless you're dealing in controller logic where having multiple instances of a class corresponding to a single device could result in major system problems, a database connection class*, or some other such thing), as it's essentially an attempt at creating global state. I understand that the Java world demands that some patterns be implemented as singletons (I've seen too many unnecessary factories implemented as singletons because Java-thought demands it). However, Python is not Java, and attempting to write Java in Python will result in a lot of pain. However, should you absolutely need a singleton in Python (and you likely don't), perhaps the most Pythonic way of doing it would be to break off a module and treat it as though it were a class. This would do a better job of enforcing the singleton contract (importing something once and only once), due to the way Python handles importing other modules. In the case I'm looking at, it's a high level class that manages everything going on in the program. Lots of objects in the program need access to this class instance. Is this a good usecase for this approach? NO! In fact, that's one of the worst use cases for a singleton. You've essentially created a God object. Your code is likely to be using objects when some other construction would be less complicated. *Unless you're maintaining your DBMS's Python interface, I have to wonder why you're doing such a thing.
Find elsewhere
🌐
W3Schools
w3schools.com › python › gloss_python_self.asp
Python Self
Python Examples Python Compiler ... Training ... The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class....
🌐
Python.org
discuss.python.org › python help
Python class __init__ and self - Python Help - Discussions on Python.org
October 4, 2024 - My question what do self an init mean in python class? like this: class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart so why I have to do that? And what do th…
🌐
Medium
medium.com › @mamchinn › pythons-init-method-and-self-the-key-to-understanding-object-oriented-programming-43003eb0c6c2
Python’s __init__ Method and self: The Key to Understanding Object-Oriented Programming | by Andrew Mamchyn | Medium
March 3, 2023 - As you can see the memory locations are the same so we proved that Python injects instance object as a first argument. Now, by convention we call this argument self. You don’t have to call it self you can call it Carl if it makes you happy but it’s better to stick to conventions for the better readability. class Person: name = "Jason" def greeting(self): print("Hello there")
Top answer
1 of 2
4
Good question! In self.__class__.__name__: * "self" is represents the instance of the class: kenneth * The attribute __class__ is set to the type of the instance. In this case it is set to point to the Thief class obj: kenneth.__class__ returns * When the class instance is initiated, the __name__ attribute of the __class__ is assigned to the name "Thief": kenneth.__class__.__name__ returns "Thief" Answering @anthony pizarro (https://teamtreehouse.com/anthonypizarro): What does **__ do? Can anything be __x__?** The double underscores __ beginning and ending a method name is a naming convention signifying this method is one of the special methods predefined within the Python language. They are also nicknamed “dunder” method for double underscore. See Python data model (https://docs.python.org/3/reference/datamodel.html) for complete list. It is not recommended to create your own new dunder method. What is the “.” for? The dot (“.”) syntax is used to mean “an attribute of”. So the code Python self.__class__"."__name__ would mean, the __name__ attribute of the __class__ attribute, of self which is the current instance of the class What if i had two files one for Thief and another for Pirate? In both cases, the __class__.__name__ would be set to the name of the defined class. So Thief and Pirate would get the correct name. As always, post back if you have more questions. Good Luck!!
2 of 2
0
what if i had two files one for Thief and another for Pirate. if i use self.__class__"."__name__, self.name how would the program know which file to use. would there need to be a new line of code in def __init__ (self....) asking for a character? and why do we use __class__ , what does __ actually do can anything be __x__ i have re watch the video over and over again , but i dont understand what hes doing or why there's a period in there "" [MOD: Edited for clarity -cf]
🌐
Real Python
realpython.com › python3-object-oriented-programming
Object-Oriented Programming (OOP) in Python – Real Python
December 15, 2024 - You can give .__init__() any number of parameters, but the first parameter will always be a variable called self. When you create a new class instance, then Python automatically passes the instance to the self parameter in .__init__() so that Python can define the new attributes on the object.
🌐
Insightsreal
crisis.insightsreal.com › self-in-python-class.html
Why Self Matters in Python Classes and How to Use It
April 24, 2025 - Here, self.name and self.breed means that each Dog object will have its own name and breed values. Without self, Python would have no idea where to store these details. In simple words, the self connects the dots between the object and its properties. You might have noticed that every method inside a class always has self as its first parameter.
🌐
PREP INSTA
prepinsta.com › home › python tutorial › self in python class
Self in Python class | Python Keywords | Python Tutorial | PrepInsta
April 15, 2021 - self represents the instance of the class. By using the “self” keyword we can access the attributes and methods of the class in python.
Top answer
1 of 2
1

employee, __init__, and add_employee are just attributes of the class Workers.

employee is an attribute being a list, and __init__ is another attribute, being a method.

Also from the def documentation:

A function definition is an executable statement. Its execution binds the function name in the current local namespace to a function object (a wrapper around the executable code for the function).

so employees and __init__ and all other methods are really the same: names in a namespaces.

See also https://docs.python.org/3/tutorial/classes.html#class-objects

2 of 2
0

The employee object is a class variable, not an instance variable. This means it is shared across all instances of that class. You can access it with classname.classvariablename or instancename.classvariablename. If you reassign an instance's version of it with something like instancename.classvariablename = newvalue, that instance will have a new instance variable of that name that masks its access to the class variable with the self reference (i.e., you won't be able to do instancename.classvariablename to get the class variable), but other instances - and the class - will still be able to (i.e., classname.classvariable will still work, and otherinstancename.classvariable will still point to that class variable). The following example demonstrates this.

>>> class A:
...     l = []
...
>>> a = A()
>>> b = A()
>>> a.l
[]
>>> A.l
[]
>>> a.l = 3
>>> b.l
[]
>>> b.l.append(1)
>>> b.l
[1]
>>> A.l
[1]
>>> a.l
3
🌐
Python Morsels
pythonmorsels.com › what-is-self
Python's self - Python Morsels
December 28, 2020 - Some programming languages use the word this to represent that instance, but in Python we use the word self. When you define a class in Python, every method that you define must accept that instance as its first argument (called self by convention).
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):

🌐
Python.org
discuss.python.org › python help
Implicit accessing of __class__ - Python Help - Discussions on Python.org
November 13, 2022 - Hi there Recently, I saw someone wrote code like this: class A: def __init__(self): print(__class__) # -> A print(self.__class__) # -> A A() I didn’t know that it worked! Why can __class__ attribute be accessed without an instance, exceptionally? Why cannot other attributes such as __mro__, ...
Top answer
1 of 5
69

It's to allow chaining.

For example:

var Car = function () {
    return {
        gas : 0,
        miles : 0,
        drive : function (d) {
            this.miles += d;
            this.gas -= d;
            return this;
        },
        fill : function (g) {
            this.gas += g;
            return this;
        },
    };
}

Now you can say:

var c = Car();
c.fill(100).drive(50);
c.miles => 50;
c.gas => 50;
2 of 5
11

As @Lie Ryan and @Frank Shearar mention, that's called a "fluent interface" but that pattern has been around for a really long time.

The controversial part of that pattern is that in OO, you have mutable state, so a void method has a kind of implied return value of this -- that is, the object with updated state is kind of the return value.

So in an OO language with mutable state, these two are more or less equivalent:

a.doA()
a.doB()
a.doC()

...as opposed to

a.doA().doB().doC()

So I've heard people in the past resist fluent interfaces because they like the first form. Another name I've heard for "fluent interface" is "train wreck" ;)

I say "more or less equivalent", though, because fluent interfaces add a wrinkle. They don't have to "return this". They can "return new". That's a way of attaining immutable objects in OO.

So you could have a class A that does (pseudocode)

function doA():
    return new A(value + 1)

function doB():
    return new A(value * 2)

function doC():
    return new A(sqrt(value))

Now, each method returns a brand new object, leaving the initial object unchanged. And that's a way of getting into immutable objects without really changing much in your code.