Magic Methods
Python - Magic or Dunder Methods
Section titled “Python - Magic or Dunder Methods”Magic methods in Python are the special methods that start and end with the double underscores. They are also called dunder methods. Magic methods are not meant to be invoked directly by you, but the invocation happens internally from the class on a certain action. For example, when you add two numbers using the + operator, internally, the add() method will be called.
__add__()
Built-in classes in Python define many magic methods. Use the dir() function to see the number of magic methods inherited by a class. For example, the following lists all the attributes and methods defined in the int class.
dir()``int
print(dir(int))
#output:#['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__',#'__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__',#'__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__',#'__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__',#'__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__',#'__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__',#'__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__',#'__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__',#'__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length',#'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']`print(dir(int))
#output:
#[‘abs’, ‘add’, ‘and’, ‘bool’, ‘ceil’, ‘class’, ‘delattr’,
#‘dir’, ‘divmod’, ‘doc’, ‘eq’, ‘float’, ‘floor’, ‘floordiv’,
#‘format’, ‘ge’, ‘getattribute’, ‘getnewargs’, ‘gt’, ‘hash’,
#‘index’, ‘init’, ‘init_subclass’, ‘int’, ‘invert’, ‘le’,
#‘lshift’, ‘lt’, ‘mod’, ‘mul’, ‘ne’, ‘neg’, ‘new’, ‘or’,
#‘pos’, ‘pow’, ‘radd’, ‘rand’, ‘rdivmod’, ‘reduce’, ‘reduce_ex’,
#‘repr’, ‘rfloordiv’, ‘rlshift’, ‘rmod’, ‘rmul’, ‘ror’, ‘round’,
#‘rpow’, ‘rrshift’, ‘rshift’, ‘rsub’, ‘rtruediv’, ‘rxor’, ‘setattr’,
#‘sizeof’, ‘str’, ‘sub’, ‘subclasshook’, ‘truediv’, ‘trunc’, ‘xor’, ‘bit_length’,
#‘conjugate’, ‘denominator’, ‘from_bytes’, ‘imag’, ‘numerator’, ‘real’, ‘to_bytes’][Try it](/codeeditor?cid=python-3z8uxfuwt) As you can see above, the int class includes various magic methods surrounded by double underscores. For example, the __add__ method is a magic method which gets called when we add two numbers using the + operator. Consider the following example. add`
num=10res = num.__add__(5)print(res)num=10 res = num.__add__(5) print(res)Try it
As you can see, when you do num+10, the + operator calls the add(10) method. You can also call num.add(5) directly which will give the same result. However, as mentioned before, magic methods are not meant to be called directly, but internally, through some other methods or actions.
num+10``__add__(10)``num.__add__(5)
Magic methods are most frequently used to define overloaded behaviours of predefined operators in Python. For instance, arithmetic operators by default operate upon numeric operands. This means that numeric objects must be used along with operators like +, -, *, /, etc. The + operator is also defined as a concatenation operator in string, list and tuple classes. We can say that the + operator is overloaded.
In order to make the overloaded behaviour available in your own custom class, the corresponding magic method should be overridden. For example, in order to use the + operator with objects of a user-defined class, it should include the add() method.
__add__()
Let’s see how to implement and use some of the important magic methods.
new() method
Section titled “new() method”Languages such as Java and C# use the new operator to create a new instance of a class. In Python the new() magic method is implicitly called before the init() method. The new() method returns a new object, which is then initialized by init().
__new__()``__init__()``__new__()``__init__()
class Employee: def __new__(cls): print ("__new__ magic method is called") inst = object.__new__(cls) return inst def __init__(self): print ("__init__ magic method is called") self.name='Satya'class Employee: def __new__(cls): print ("__new__ magic method is called") inst = object.__new__(cls) return inst def __init__(self): print ("__init__ magic method is called") self.name='Satya'Try it
The above example will produce the following output when you create an instance of the Employee class. The new() method is called before the init() method.
Employee``__new__()``__init__()
str() method
Section titled “str() method”Another useful magic method is str(). It is overridden to return a printable string representation of any user defined class. We have seen str() built-in function which returns a string from the object parameter. For example, str(12) returns ‘12’. When invoked, it calls the str() method in the int class.
__str__()``str()``str(12)``__str__()
num=12val = int.__str__(num)print(type(val))num=12 val = int.__str__(num) print(type(val))Try it
Let us now override the str() method in the employee class to return a string representation of its object.
__str__()``employee
class employee: def __init__(self): self.name='Swati' self.salary=10000 def __str__(self): return 'name='+self.name+', salary=$'+str(self.salary)
e1 = employee()print(e1)`class employee: def init(self): self.name=‘Swati’ self.salary=10000 def str(self): return ‘name=‘+self.name+’, salary=$‘+str(self.salary)
e1 = employee()
print(e1)[Try it](/codeeditor?cid=python-3z8ww77xe) The str() function internally calls the __str__() method defined in the above employee class. This is why it is called a magic method! str()__str__()employee`
add() method
Section titled “add() method”In following example, a class named distance is defined with two instance attributes - ft and inch. The addition of these two distance objects is desired to be performed using the overloading + operator.
To achieve this, the magic method add() is overridden, which performs the addition of the ft and inch attributes of the two objects. The str() method returns the object’s string representation.
__add__()``__str__()
class distance: def __init__(self, x=None,y=None): self.ft=x self.inch=y def __add__(self,x): temp=distance() temp.ft=self.ft+x.ft temp.inch=self.inch+x.inch if temp.inch>=12: temp.ft+=1 temp.inch-=12 return temp def __str__(self): return 'ft:'+str(self.ft)+' in: '+str(self.inch)
d1=distance(3,10)d2=distance(4,4)print("d1= {} d2={}".format(d1, d2))
d3=d1+d2print(d3)`class distance: def init(self, x=None,y=None): self.ft=x self.inch=y def add(self,x): temp=distance() temp.ft=self.ft+x.ft temp.inch=self.inch+x.inch if temp.inch>=12: temp.ft+=1 temp.inch-=12 return temp def str(self): return ‘ft:‘+str(self.ft)+’ in: ‘+str(self.inch)
d1=distance(3,10) d2=distance(4,4) print(“d1= {} d2={}“.format(d1, d2))
d3=d1+d2
print(d3)[Try it](/codeeditor?cid=python-3z8wwaz8z) The example overloades the __add__() method which will be called when adding two objects using the + operator. add()`
ge() method
Section titled “ge() method”The following method is added in the distance class to overload the >= operator.
>=
class distance: def __init__(self, x=None,y=None): self.ft=x self.inch=y def __ge__(self, x): val1=self.ft*12+self.inch val2=x.ft*12+x.inch if val1>=val2: return True else: return False
d1=distance(2,1)d2=distance(4,10)print(d1>=d2)`class distance: def init(self, x=None,y=None): self.ft=x self.inch=y def ge(self, x): val1=self.ft12+self.inch val2=x.ft12+x.inch if val1>=val2: return True else: return False
d1=distance(2,1)
d2=distance(4,10)
print(d1>=d2)The __ge__() method gets invoked when the >= operator is used and returns True or False. Accordingly, the appropriate message can be displayed.ge()“>=`
Important Magic Methods
Section titled “Important Magic Methods”The following tables list important magic methods in Python 3.
Thus, you can use the appropriate magic methods to add various functionalities in your custom class.