python class special methods or magic methods. magic methods allow us to override or add the default functionality of python objects. One of the biggest advantages of using Python's magic methods is that they provide a simple way to make objects behave like built-in types. That means you can avoid ugly, counter-intuitive, and nonstandard ways of performing basic operators.
In this blog posts lets discuss about using magic methods/special methods in python development
What happens when we create an object in python class?
class Address(object):
def __init__(self, city, pin):
self.city = city
self.pin = pin
creating instance of the object
a = Address("hyderabad", "500082")
before creating the instance of the class "__new__" method will be called. This method takes parameter "class", "args", "kwargs" and It will bind the data type to given class. After it will call the "__init__" method with arguments and keyword arguments.
>>> a = Address.__new__(Address)
>>> type(a)
__main__.Address
>>> a.city
AttributeError: 'Address' object has no attribute 'city'
# object created but not initialised that's the reason we get error
>>> a.__init__("hyderabad", "500082")
# now we can access the attributes
>>> a.city
'hyderabad'
we can cosider bilt-in methods of an object as magic methods. We can also override the built-in methods functionality.
list of magic methods:
Binary Operators
Operator Method
+ object.__add__(self, other)
- object.__sub__(self, other)
* object.__mul__(self, other)
// object.__floordiv__(self, other)
/ object.__div__(self, other)
% object.__mod__(self, other)
** object.__pow__(self, other[, modulo])
<< object.__lshift__(self, other)
>> object.__rshift__(self, other)
& object.__and__(self, other)
^ object.__xor__(self, other)
| object.__or__(self, other)
Assignment Operators:
Operator Method
+= object.__iadd__(self, other)
-= object.__isub__(self, other)
*= object.__imul__(self, other)
/= object.__idiv__(self, other)
//= object.__ifloordiv__(self, other)
%= object.__imod__(self, other)
**= object.__ipow__(self, other[, modulo])
<<= object.__ilshift__(self, other)
>>= object.__irshift__(self, other)
&= object.__iand__(self, other)
^= object.__ixor__(self, other)
|= object.__ior__(self, other)
Unary Operators:
Operator Method
- object.__neg__(self)
+ object.__pos__(self)
abs() object.__abs__(self)
~ object.__invert__(self)
complex() object.__complex__(self)
int() object.__int__(self)
long() object.__long__(self)
float() object.__float__(self)
oct() object.__oct__(self)
hex() object.__hex__(self)
Comparison Operators
Operator Method
< object.__lt__(self, other)
<= object.__le__(self, other)
== object.__eq__(self, other)
!= object.__ne__(self, other)
>= object.__ge__(self, other)
> object.__gt__(self, other)
Let's take an example to override the functionality "+" [__add__] operator
class Vector(object):
def __init__(self, *args):
""" Create a vector, example: v = Vector(1,2) """
if len(args) == 0:
self.values = (0,0)
else:
self.values = args
def __add__(self, other):
""" Returns the vector addition of self and other """
added = tuple(a + b for a, b in zip(self.values, other.values) )
return Vector(*added)
now use the "+" operator with two vectors
>>> v1 = Vector(1, 2)
>>> v2 = Vector(10, 13)
>>> v3 = v1 + v2
>>> v3.values
(11, 15)
When statement "v3 = v1 + v2 " executes "__add__" is called and it returns a new Vector object.
for more information please visit the python docs