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