Eric Brauer
Integers can be printed (even though they are not strings), and they can be compared to floats (even though they are different datatypes). This is intuitive behaviour, it makes sense to us even though it shouldn’t be possible.
How objects behave is defined in their help documentation. Try looking at this now.
Running the builtin help()
will show you all the
methods that belong to integer objects.
Notice all the methods that start & end with __? These are dunder methods (“double underline”). Otherwise called magic methods.
We don’t call these methods directly by name.
Rather these are called when we use the object with different operators or builtin functions.
When we use the integer object with a == symbol, we are actually
calling the __eq__
method, which will return a True or
False.
__eq__
For operators, “self” will refer to the left side of the equation, and “other” will refer to the right.
Every built-in object in Python will be implementing a lot of these magic methods. This helps us because it means that objects in Python will behave in predictable ways. By implementing magic methods in our classes, we can allow the user to use our objects in intuitive ways.
Let’s say we want to create a new object for storing temperature. Most countries measure temperature in Celsius, but we might also want to accommodate people who measure in Fahrenheit.
Class Temperature:
def __init__(self, temp, unit):
self.temp = temp
self.unit = unit
def rtrn_celsius(self):
if self.unit == 'F':
return self.temp / 1.8 - 32
else:
return self.temp
def rtrn_fahrenheit(self):
if self.unit == 'C':
return self.temp * 1.8 + 32 # equation to convert C to F.
else:
return self.temp
def return_unit(self):
return self.unit
==
It might be more intuitive when comparing temperatures if we let our == symbol ‘detect’ the unit of the other temperature.
def __eq__(self, other):
if other.return_unit() == 'C':
return self.rtrn_celsius() == other.rtrn_celsius()
elif other.return_unit() == 'F':
return self.rtrn_fahrenheit() == other.rtrn_fahrenheit()
Programmers would rather use the operators they already know about, than have to read the documentation and discover all of your named methods!
Let’s create a timer object. Timer
is going to expect
minutes and seconds. In other words, this is setting up a timer for
02:00.
This output isn’t very useful to the programmer. We need to define
the behaviour for when our object is used with a builtin
function, in this case the print()
function.
f-strings are a more advanced method of printing. They don’t need manual conversion! Simply put an ‘f’ outside of your quotes, and then variable names inside of curly braces.
:02d
will convert to a 2 digit
decimal number with leading zeros, eg. 02.repr is used inside the Python interpreter. It will
return a representation of the object, when you call the object
outside of print()
or str()
.
>>>> t = Timer(2, 0)
>>>> t # calls __repr__
<template.Timer object at 0x7f199cb4f820>
>>>> print(t) # calls __str__
02:00
If you define only __repr__
, it will also be used for
__str__
, so it’s better to just write __repr__
(unless you want different outputs!)