Python Magic Methods: a practical example

NachoGentile 3,265 views 9 slides Mar 21, 2014
Slide 1
Slide 1 of 9
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9

About This Presentation

Brief overview about magic methods in Python and how they can be used.


Slide Content

Python magic methods
by Nacho Gentile

What is a method?
•A method is similar to a function except it’s a member of
an object or class.
•Normally, we use the syntax object.method() to call a
method, for example datetime.now()
•The first parameter of an object method is always “self”
Example of method:
class Runner:
def run(self, meters):
pass

What are magic methods
•Special methods that you can define to add
“magic” to your classes
•Magic methods are surrounded by two
underscores, e.g. __init__

Some of the things we can
do with magic methods
•Give instructions to classes about what to do when creating an object
obj1 = MyClass() # __init__
!
•Explain classes how to arithmetically add together
obj1 + obj2 # __radd__
!
•Define how the object will look like when printed
print obj1 # __str__
•Explain classes how to perform boolean operations on them
obj1 > obj2 # __gt__, __lt__, __cmp__

The runners example
•We need to represent runners profile for a runners
website
•Each runner profile is related to a list of race statistics
•Each race statistic tracks distance ran and calories
used during the race
•We want to know: the total statistics for all races
(distance and calories) and to compare runners by
total distances made.

The runners example
class RaceStatistics:
def __init__(self, distance, calories):
self.distance = distance
self.calories = calories
!
def __radd__(self, other):
if other.__class__ == self.__class__:
return RaceStatistics(self.distance + other.distance,
self.calories + other.calories)
else:
return self

class Runner:
def __init__(self, name):
self.name = name
self.races = []
!
def __str__(self):
return "Runner %s" % self.name
!
def add_race(self, distance, calories):
new_run = RaceStatistics(distance, calories)
self.races.append(new_run)
!
def get_all_races_statistics(self):
return sum(self.races)
!
def get_total_distance(self):
return self.get_all_races_statistics().distance
!
def get_total_calories(self):
return self.get_all_races_statistics().calories
!
def __cmp__(self, other):
return self.get_total_distance() == other.get_total_distance()
!
def __lt__(self, other):
return self.get_total_distance() < other.get_total_distance()
!
def __gt__(self, other):
return self.get_total_distance() > other.get_total_distance()

nacho = Runner("Nacho")
nacho.add_race(distance=15, calories=150)
nacho.add_race(distance=20, calories=450)
nacho.add_race(distance=14, calories=250)
!
manuel = Runner("Manuel")
manuel.add_race(distance=15, calories=150)
manuel.add_race(distance=20, calories=450)
manuel.add_race(distance=14, calories=250)
!
print nacho
> Runner Nacho
!
nacho.get_total_distance()
> 49
!
nacho.get_total_calories()
> 850
!
nacho == manuel
> True
!
manuel.add_race(distance=14, calories=250)
!
if nacho > manuel:
print "%s is the best runner" % nacho
elif nacho < manuel:
print "%s is the best runner" % manuel
else:
print "%s and %s are both good" % (nacho, manuel)
> Runner Manuel is the best runner

Thank you