Python Tutorial_ Magic Methods
Python Tutorial_ Magic Methods
Home Python 2 Tutorial Python 3 Tutorial Advanced Topics Numerical Programming Machine Learning Tkinter Tutorial Contact
Japanese Food
class Length:
and OOP
__metric = {"mm" : 0.001, "cm" : 0.01, "m" : 1, "km" : 1000,
"I think both Object- "in" : 0.0254, "ft" : 0.3048, "yd" : 0.9144,
Oriented "mi" : 1609.344 }
Programming and
def __init__(self, value, unit = "m" ):
Japanese food are
self.value = value
significant aesthetic self.unit = unit
and stylistic
achievements - def Converse2Metres(self):
they're both about return self.value * Length.__metric[self.unit]
taking simple meager
ingredients and def __add__(self, other):
l = self.Converse2Metres() + other.Converse2Metres()
making something
return Length(l / Length.__metric[self.unit], self.unit )
remarkable.", Sean
M. Burke def __str__(self):
return str(self.Converse2Metres())
This website is It's a safe bet that if somebody works for a while with adding integers and floats from the right sight that he or she wants to the same from the left side! So let's try it out:
supported by:
>>> from unit_conversions import Length
Linux and Python >>> x = Length(3, "yd") + 5
>>> x = 5 + Length(3, "yd")
Courses and
Traceback (most recent call last):
Seminars File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'Length'
>>>
Of course, the left side has to be of type "Length", because otherwise Python tries to apply the __add__ method from int, which can't cope with Length objects as second arguments!
Python provides a solution for this problem as well. It's the __radd__ method. It works like this: Python tries to evaluate the expression "5 + Length(3, 'yd')". First it calls int.__add__(5,Length(3, 'yd')), which will
raise an exception. After this it will try to invoke Length.__radd__(Length(3, "yd"), 5). It's easy to recognize that the implementation of __radd__ is analogue to __add__:
It's advisable to make use of the __add__ method in the __radd__ method:
The following diagram illustrates the relationship between __add__ and __radd__:
The __call__ method can be used to turn the instances of the class into callables. Functions are callable objects. A callable object is an object which can be used and behaves like a function but might not be a
function. By using the __call__ method it is possible to define classes in a way that the instances will be callable objects. The __call__ method is called, if the instance is called "like a function", i.e. using brackets.
The following example defines a class with which we can create abitrary polynomial functions:
class Polynomial:
# a constant function
p1 = Polynomial(42)
# a straight Line
p2 = Polynomial(0.75, 2)
1 42 2.75 3.25
2 42 3.5 9.5
3 42 4.25 26.75
4 42 5.0 61.0
5 42 5.75 118.25
6 42 6.5 204.5
7 42 7.25 325.75
8 42 8.0 488.0
9 42 8.75 697.25
You will find further interesting examples of the __call__ function in our tutorial in the chapters Decorators and Memoization with Decorators. You may also consult our chapter on Polynomials
It's possible to use standard classes - like int, float, dict or lists - as base classes as well.
class Plist(list):
if __name__ == "__main__":
x = Plist([3,4])
x.push(47)
print(x)
This means that all the previously introduced binary and extended assignment operators exist in the "reversed" version as well:
__radd__
__rsub__
__rmul__
...
and so on
Exercises
1. Write a class with the name Ccy, similar to the previously defined Length class.
Ccy should contain values in various currencies, e.g. "EUR", "GBP" or "USD". An instance should contain the amount and the currency unit.
The class, you are going to design as an excercise, might be best described with the following example session:
1. First exercise:
"""
The class "Ccy" can be used to define money values in various currencies. A Ccy instance has the string attributes 'unit' (e.g. 'CHF', 'CAD' od 'EUR' and the 'value' as a
float.
A currency object consists of a value and the corresponding unit.
"""
class Ccy:
def __str__(self):
return "{0:5.2f}".format(self.value) + " " + self.unit
x = Ccy(10,"USD")
y = Ccy(11)
z = Ccy(12.34, "JPY")
z = 7.8 + x + y + 255 + z
print(z)
z = sum(lst)
print(z)
282.91 EUR
28.40 EUR
Another interesting aspect of this currency converter class in Python can be shown, if we add multiplication. You will easily understand that it makes no sense to allow expressions like "12.4 € * 3.4
" (orinpraef ixnotation :" €12.4∗ 3.4"), but it makes perfect sense to evaluate "3 * 4.54 €". You can find the new currency converter class with the newly added methods for __mul__, __imul__ and __rmul__
"""
The class "Ccy" can be used to define money values in various currencies. A Ccy instance has the string attributes 'unit' (e.g. 'CHF', 'CAD' od 'EUR' and the 'value' as a
float.
A currency object consists of a value and the corresponding unit.
"""
class Ccy:
def __str__(self):
return "{0:5.2f}".format(self.value) + " " + self.unit
def __repr__(self):
return 'Ccy(' + str(self.value) + ', "' + self.unit + '")'
Assuming that you have saved the class under the name currency_converter, you can use it in the following way in the command shell:
We can further improve our currency converter class by using a function get_currencies, which downloads the latest exchange rates from finance.yahoo.com. This function returns an exchange rates dictionary
in our previously used format. The function is in a module called exchange_rates.py This is the code of the function exchange_rates.py:
def get_currency_rates(base="USD"):
""" The file at location url is read in and the exchange rates are extracted """
url = "https://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote"
data = urlopen(url).read()
data = data.decode('utf-8')
soup = BeautifulSoup(data, 'html.parser')
data = soup.get_text()
flag = False
currencies = {}
for line in data.splitlines():
if flag:
value = float(line)
flag = False
currencies[currency] = value
if line.startswith("USD/"):
flag = True
currency = line[4:7]
return currencies
We can import this function from our module. (You have to save it somewhare in your Python path or the directory where your program runs):
class Ccy:
currencies = get_currencies()
Footnotes
© 2011 - 2018, Bernd Klein, Bodenseo; Design by Denise Mitchinson adapted for python-course.eu by Bernd Klein