English English

Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/ard-site/templates/ardsite/library/Designer/Content/SingleArticle.php on line 198

Dunder / Magic methods - Method and operator overloading in Python

You can use magic methods (also called dunder methods) in your Python class to override certain functionality of your class instance.

Some examples of magic methods are "__repr__", "__hash__", "__get__" and more. These are part of the Python 3 data model.

 

"__repr__" - String representation

This method allows you to define a string output for every class instance that is created. You will get as an output the memory address of the called class instance, if you call a class instance of a class without this method "__repr__".

class Car:
    def __init__(self, manufacturer, model):
        self.manufacturer = manufacturer
        self.model = model

    def __repr__(self):
        return self.manufacturer + " - " + self.model

if  __name__ == '__main__':
    bluecar1 = Car("The Car Company" , "XY 199")
    print(bluecar1)

But you can instead print with this method your own defined string. "__init__" is an constructor implementation and it allows to define what should hapen when an instance of this class is created. In this method you will have the definition of the variable of a class instance.

 

"__hash__" - Customized hash for hashable objects

If you use for example collections (such as "set", "frozenset" or "dict"), then you can customize the creation of the hash value of your object.

class Car:
    def __init__(self, manufacturer, model):
        self.manufacturer = manufacturer
        self.model = model

    def __hash__(self):
        return int(hash(self.manufacturer)%10000)

if  __name__ == '__main__':
    bluecar1 = Car("The Car Company" , "XY 199")
    print(bluecar1.__hash__())	

In this example the hash value of objects cannot have more than four digits and it is created from string object "manufacturer".

 

"__get__" - Value of variable of a class instance

This method is called when a variable of an class instance is accessed. You can override so it returns a custom value instead.

class EndPrice:
    def __get__(self, instance, owner):
        if instance.manufacturer=="The Car Company":
            return instance.stockprice-(instance.stockprice*0.10)
        else:
            return instance.stockprice-(instance.stockprice*0.05)

class Car:
    endprice = EndPrice()

    def __init__(self, manufacturer, model, stockprice):
        self.manufacturer = manufacturer
        self.model = model
        self.stockprice = stockprice

    def __repr__(self):
        return self.manufacturer + " - " + self.model

		
if  __name__ == '__main__':
	bluecar1 = Car("The Car Company" , "XY 199", 2000)
	print(bluecar1.endprice)
	redcar1 = Car("NoName Company" , "ZZ 2", 2000)
	print(redcar1.endprice)

If you access a variable (in this example: "endprice") of your class instance object, then Python calls the method "__get__(instance, owner)" in the background. "instance" is the class instance for which the class variable is called. "owner" is who own this class object and it is an optional argument.

"__set__" is also available. You can also change how values of a variable are set.

Example:

    def __set__(self, instance, value):
        instance.stockprice = value * 100

In this example we convert the stock price automatically to cents.

 

"__add__" / "__sub__" - Arithmetical methods

You can use these methods to change values of variables in your class instance, when an arithmetic operator was used.

class Car:

    def __init__(self, manufacturer, model, stockprice):
        self.manufacturer = manufacturer
        self.model = model
        self.stockprice = stockprice

    def __add__(self, other):
        if type(other) is int:
            self.stockprice + other
        else:
            raise Exception("Please enter only an integer value!")

    def __sub__(self, other):
        if type(other) is int:
            self.stockprice - other
        else:
            raise Exception("Please enter only an integer value!")

    def __repr__(self):
        return str(self.stockprice)


if  __name__ == '__main__':
    bluecar1 = Car("The Car Company" , "XY 199", 2000)
    bluecar1 + 2000
    print(bluecar1)
    bluecar1 - 1000
    print(bluecar1)

"__add__" is called when you do an addition ("+") with another class instance variable or value. "__sub__" when you do an substraction ("-").


There are also other arithmetical methods:

"__mul__": For multiplication - Operator: "*"
Example:

def __mul__(self, other):
  self.stockprice * other

classobject1 * classobject2

 

"__truediv__": For division - Operator: "/"

def __truediv__(self, other):
  self.stockprice / other

classobject1 / classobject2

 

Comparison operators

"__lt__" - Lower than - Comparison

You can override that method to return a certain string when a "lower than" comparison is done with two class instance objects. This method is called through the operator "<".

class Car:

    def __lt__(self, other):
        if other.stockprice < self.stockprice:
            return "Second car cheaper than first car"
        else:
            return "Second car is NOT cheaper than first car"


if  __name__ == '__main__':
    bluecar1 = Car("The Car Company" , "XY 199", 2000)
    redcar1 = Car("NoName Company" , "ZZ 2", 3000)
    print(bluecar1<redcar1)

 

Other comparison methods

  • "__le__" - lower equals - Operator: "<="
  • "__eq__" - equals - Operator: "="
  • "__ne__" - not equals - Operator: "!="
  • "__gt__" - greater than - Operator: >
  • "__ge__" - greater equals - Operator: ">="

All these methods have also the argument variable "other", such as in our example "__lt__" above.

There are much more magic methods such as "__len__" (changes "len" value of an object) and more. New methods are introduced in every new Python version. Please refer to the Python documentation for more information.

More about magic methods:
https://docs.python.org/3/reference/datamodel.html#special-method-names

 

 

We use cookies on our website. They are essential for the operation of the site
Ok