Magic Methods

Python has a number of special methods, also known as dunder methods as they begin (and end) with a double underscore. Also called magic methods, they enable many of Python’s built-in functions to operate on your objects. These methods are not meant to be invoked directly.

For example, the __init__ special method used to initialise a newly created object:

class Person:
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

Python has many more of these methods to facilitate and support:

  • iteration
  • collections
  • attribute access
  • operator overloading
  • method invocation
  • object construction and destruction
  • string representation
  • managed context

You can determine which special methods an object has implemented with the dir() function:

from pprint import pprint

pprint([x for x in dir(str) if x.startswith('__')])

# outputs:

['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__getnewargs__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mod__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rmod__',
 '__rmul__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__']

Here is a simple example:

class CricketTeam:
    def __init__(self, name, *args):
        self.name = name
        self.players = []

        for name in args:
            self.players.append(name)

    def __len__(self):
        return len(self.players)

    def __getitem__(self, index):
        if 0 <= index < len(self.players):
            return self.players[index]

    def __setitem__(self, index, name):
        if 0 <= index < len(self.players):
            self.players.append(name)

    def __iter__(self):
        return iter(self.players)


aussies = CricketTeam('Australia',
               'Matthew Hayden',
               'Justin Langer',
               'Ricky Ponting',
               'Michael Clark',
               'Mark Waugh',
               'Steve Waugh',
               'Adam Gilchrist',
               'Shane Warne',
               'Brett Lee',
               'Mitchell Johnson',
               'Glen McGrath')

print(f'There are {len(aussies)} players')
print(f'Captain: {aussies[5]}')

for i, player in enumerate(aussies):
    print(f'{i+1}. {player}')

# outputs:

There are 11 players

Captain: Steve Waugh

1. Matthew Hayden
2. Justin Langer
3. Ricky Ponting
4. Michael Clark
5. Mark Waugh
6. Steve Waugh
7. Adam Gilchrist
8. Shane Warne
9. Brett Lee
10. Mitchell Johnson
11. Glen McGrath

Here are a few more special methods, the list is not exhaustive – for more information see the official docs:

Initialization and Construction

  • new(cls, other) To get called in an object’s instantiation
  • init(self, other) To get called by the new method
  • del(self) destructor method

Unary operators and functions

  • pos(self) To get called for unary positive e.g. +someobject
  • neg(self) To get called for unary negative e.g. -someobject
  • abs(self) To get called by built-in abs() function
  • invert(self) To get called for inversion using the ~ operator
  • round(self,n) To get called by built-in round() function
  • floor(self) To get called by built-in math.floor() function
  • ceil(self) To get called by built-in math.ceil() function
  • trunc(self) To get called by built-in math.trunc() function

Augmented Assignment

  • iadd(self, other) To get called on addition with assignment e.g. a +=b
  • isub(self, other) To get called on subtraction with assignment e.g. a -=b
  • imul(self, other) To get called on multiplication with assignment e.g. a *=b
  • ifloordiv(self, other) To get called on integer division with assignment e.g. a //=b
  • idiv(self, other) To get called on division with assignment e.g. a /=b
  • itruediv(self, other) To get called on true division with assignment
  • imod(self, other) To get called on modulo with assignment e.g. a%=b
  • ipow(self, other) To get called on exponentswith assignment e.g. a **=b
  • ilshift(self, other) To get called on left bitwise shift with assignment e.g. a<<=b
  • irshift(self, other) To get called on right bitwise shift with assignment e.g. a >>=b
  • iand(self, other) To get called on bitwise AND with assignment e.g. a&=b
  • ior(self, other) To get called on bitwise OR with assignment e.g. a|=b
  • ixor(self, other) To get called on bitwise XOR with assignment e.g. a ^=b

Type Conversion

  • int(self) To get called by built-int int() method to convert a type to an int
  • float(self) To get called by built-int float() method to convert a type to float
  • complex(self) To get called by built-int complex() method to convert a type to complex
  • oct(self) To get called by built-int oct() method to convert a type to octal
  • hex(self) To get called by built-int hex() method to convert a type to hexadecimal
  • index(self) called on type conversion to an int when the object is used in a slice expression
  • trunc(self) To get called from math.trunc() method

String Methods

  • str(self) To get called by built-int str() method to return a string representation of a type
  • repr(self) called by built-int repr() to return a machine readable representation of a type
  • unicode(self) To get called by built-int unicode() method to return an unicode string of a type
  • format(self, formatstr) called by built-int string.format() method to return a new style of string
  • hash(self) To get called by built-int hash() method to return an integer
  • nonzero(self) To get called by built-int bool() method to return True or False
  • dir(self) To get called by built-int dir() method to return a list of attributes of a class
  • sizeof(self) To get called by built-int sys.getsizeof() method to return the size of an object

Attribute Methods

  • getattr(self, name) Is called when the accessing attribute of a class that does not exist
  • setattr(self, name, value) Is called when assigning a value to the attribute of a class
  • delattr(self, name) Is called when deleting an attribute of a class

Operator Methods

  • add(self, other) To get called on add operation using + operator
  • sub(self, other) To get called on subtraction operation using – operator
  • mul(self, other) To get called on multiplication operation using * operator
  • floordiv(self, other) To get called on floor division operation using // operator
  • truediv(self, other) To get called on division operation using / operator
  • mod(self, other) To get called on modulo operation using % operator
  • pow(self, other[, modulo]) To get called on calculating the power using ** operator
  • lt(self, other) To get called on comparison using < operator
  • le(self, other) To get called on comparison using <= operator
  • eq(self, other) To get called on comparison using == operator.
  • ne(self, other) To get called on comparison using != operator
  • ge(self, other) To get called on comparison using >= operator

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s