Here I am trying to discuss about some special method attributes in python.
we define a class like
let us make a new object c with its value attribute as sum of those of objects a and b.
There are more such methods enables operator overloading for arithmetic operators
There are corresponding reflected arithmetic operators too. If we use __radd__ instead of __add__ in above example, c=a+b will be evaluated as c=b.__radd__(a). We can define custom behavior for a lot of operations other than these arithmetic operators, like attribute assignments, comparisons, unary arithmetic operations like '+', '-' etc
Now let us look on some awesome special methods which enables creation of sequence types.
We have a class mySequence
Now we can perform some list operations as follows
we define a class like
And an object instantiation is done by>>> class myClass: ... def __init__(self,value): ... self.value=value ... print 'object initialized'
>>> a=myClass(10) object initialized >>> b=myClass(20) object initializedThis seems usual but the magic is in evaluating the function myClass(value). an expression in the formmyClass(args) causes a call to __init__(self,args) defined inside class myClass.
let us make a new object c with its value attribute as sum of those of objects a and b.
>>> c=myClass(a.value+b.value) object initialized >>> c.value 30It will be awesome if we can perform
>>> c=a+b object initialized >>> c.value 30We can make this possible by including a magic function __add__ to the class definition of myClass.
>>> class myClass: ... def __init__(self,value): ... self.value=value ... print 'object initialized' ... def __add__(self,obj): ... c=myClass(self.value+obj.value) ... return cHere c=a+b is evaluated as c=a.__add__(b)
There are more such methods enables operator overloading for arithmetic operators
Operator | Special method |
- | __sub__(self, other) |
// | __floordiv__(self, other) |
/ | __div__(self, other) |
% | __mod_(self, other) |
** | __pow__ |
<< | __lshift__(self, other) |
& | __and__(self, other) |
| | __or__(self, other) |
^ | __xor__(self, other) |
There are corresponding reflected arithmetic operators too. If we use __radd__ instead of __add__ in above example, c=a+b will be evaluated as c=b.__radd__(a). We can define custom behavior for a lot of operations other than these arithmetic operators, like attribute assignments, comparisons, unary arithmetic operations like '+', '-' etc
Now let us look on some awesome special methods which enables creation of sequence types.
We have a class mySequence
>>> class mysequance: ... def __init__(self,list): ... self.value=list ... def __iter__(self): ... return iter(self.value) ... def __getitem__(self,index): ... return self.value[index] ... def __len__(self): ... return len(self.value) ... >>> s=mysequance([1,2,3,4,5,6])
Now we can perform some list operations as follows
>>> len(s) 6 >>> s[1] 2 >>> it=iter(s) >>> for i in it: ... print i ... 1 2 3 4 5 6
Nice post Dileep.
ReplyDeleteCould you please elaborate what is the difference while executing the above snippet and below.
>>> class myClass:
... def __init__(self,value):
... self.value=value
... print 'object initialized'
... def __add__(self,obj):
... return self.value + obj.value
...
>>> a=myClass(10)
object initialized
>>> b=myClass(20)
object initialized
>>> print a+b
30
On changing the __add__ method of myClass, the behavior of binary + operator associated with objects of myClass is changed in such a way that two objects of myClass, on addition, gives a new object which is having type of value attribute of myClass.
DeleteSo it simply violates closure property of + over myClass objects :-).
As a result, we cant perform
>>> a=myClass(10)
object initialized
>>> b=myClass(20)
object initialized
>>> c=myClass(10)
object initialized
>>> d=a+b+c
or something like
>>> d=(a+b)+c+a
which is possible in above snippet.
Thank you Dileep for the detailed Explanation.:-)
Delete