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.
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.
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.
Videos
Ik this is a basic question but I'm just learning to code and I'm learning about classes. For whatever reason I cannot understand or grasp the use of the self variable in fictions of classes. Hopefully someone's explanation here will help me...
I'm looking at a class definition that includes this line in its constructor. Something like:
class someClass:
def __init__(self):
self.__class__.instance = selfThen 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?
It becomes necessary to pass self argument to the functions of your class. however, your code has several problems like the initialization of var variable. You need a constructor __init__ to create the variable, after that, you will be able to modify it:
class ThisIsClass:
def __init__(self, value=0):
self.var = value
def Func(self):
self.var+=1
c = ThisIsClass()
c.Func()
print(c.var)
In the above code, the class is instantiated as an object and stored in the variable c. You can assign an initial value to var by passing an argument to the object creation, like: c = ThisIsClass(89)
Output:
1
It has to do with the right structure of programming in python. No you dont need them 100% but if you want to have a nice and clean code I would propose you to get used of them. Also when the self is declared inside the brackets after the function name, that function can retrieve (and make available) the variable (self.variable) from and to wherever inside that class.
The reason you need to use self is because Python does not use special syntax to refer to instance attributes. Python decided to do methods in a way that makes the instance to which the method belongs be passed automatically but not received automatically, the first parameter of methods is the instance the method is called on. That makes methods entirely the same as functions and leaves the actual name to use up to you (although self is the convention, and people will generally frown at you when you use something else.) self is not special to the code, it's just another object.
Python could have done something else to distinguish normal names from attributes -- special syntax like Ruby has, or requiring declarations like C++ and Java do, or perhaps something yet more different -- but it didn't. Python's all for making things explicit, making it obvious what's what, and although it doesn't do it entirely everywhere, it does do it for instance attributes. That's why assigning to an instance attribute needs to know what instance to assign to, and that's why it needs self.
Let's say you have a class ClassA which contains a method methodA defined as:
class ClassA:
def methodA(self, arg1, arg2):
... # do something
and objectA is an instance of this class.
Now when objectA.methodA(arg1, arg2) is called, python internally converts it for you as:
ClassA.methodA(objectA, arg1, arg2)
The self variable refers to the object itself.
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
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
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'.
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):

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;
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.