Advanced Uses and Overriding .__mod__
In the previous lesson, I showed you some example uses of the
% operator. In this lesson, I’m going to take you past
float and show you how to use the
% operator with different classes, including your own.
You can create a
Decimal object by passing it a string representation of the number that you’re after. You can then do multiplication on that. A
Decimal object times an integer or times a float ends up in another
But, as you might recall, there are different ways of calculating negative modulus. The
% operator uses the
floor() method, the
Decimal class uses the
trunc() method, so results from
Decimal will be closer to
And there it is again using the
Decimal class. The extra inaccuracy introduced by
float is gone, and this uses the
trunc() division method, so you get different results depending on whether you’re using ints, floats, or decimals. Everything in Python is an object—the ints, the floats, and, of course, the
Decimal objects. Operators on those objects map to methods inside of the objects.
This isn’t just a weird little implementation detail—this is also something you can take advantage of. If you want your own classes to support the
% operator, you can do that by implementing the
Here I’m going to show you a class that represents a series of integers. Inside of it, I’m going to implement the
.__mod__() method so that I can do mod math on all of the integers in the series. Let me just scroll down.
First off, in the constructor, it creates a member called
.contents where it stores what was passed in. The arguments to the constructor are looped through and appended to
self.contents and converted to
I’m supporting two different use cases. The first use case is when the object of the class encounters
% and then an integer. In this case, I’m doing a list comprehension in line 17, calculating the mod against each one of the items inside of the
.contents array, and then I’m creating a new
IntList object consisting of the old
.contents modded with that single integer.
The second use case is to mod two
IntList objects together. To keep it simple, I’m only going to support the case where the two
IntList objects are of the same length. Line 20 checks whether or not a mod is being done against another
IntList and double-checks that if it is, that the two lengths are the same.
len() operator on the
IntList objects here will end up calling
.__len__() on line 9. I enumerate through the array of items inside of this object and I perform mod against the equivalently indexed value in the other
All of this is stored inside of a list. And then on line 25, a new
IntList object is created with the results. Line 27 is a safety. If you get here, then the mod operation either wasn’t against an
int or wasn’t against an
IntList of the same length, so an error should be raised.
foo % 12 causes
% 12 to happen for each item in the list. Converting that
IntList that returns into a list presents the following result.
1 % 12 is
5 % 12 is
15 % 12 is
18 % 12 is
Become a Member to join the conversation.