Learn about the methods behind common Python syntax and how to make your objects work with these constructs.
You may have noticed that it is possible to use certain inline methods (eg,
len(my_list_or_my_string)) and grammar (eg
my_fancy_dict['some_key']) on some original species such as
dict. You’re probably curious as to why it’s not possible (yet) to use these same sentences in some of the chapters I’ve written.
original type variables (
str) have unique behaviors and respond to certain structures because they have some special methods defined in their own classes – these methods are called magical methods.
Magic methods simply refer to Special methods that start and end with a double underscore. Also called “immersion” methods.
magic methods They are not designed to be called directly, rather they are called internally from the class in a specific action or when strange syntax is encountered.
In this article, we’ll explore the magical methods that exist for common native species and how we can also make our beings display common behaviors with common native species.
But, before we dive into the special methods of each parent type, let’s go over the basic methods that are common across all variants.
__new__(self, *args, **kwargs) This is the first step in creating the instance. It is called first and is responsible for back A new instance of your class. Use this method if you want to control how new instances are created.
__init__(self, *args, **kwargs) This class method is called when we want to initialize a new instance. So, It is called immediately after creating an instance by
__new__ method. the
__init__ The method in Python does not return anything.
__call__(self, *args, **kwargs) It is sometimes possible to invoke an object in the same way that we call functions. This is made possible by
Objects would be completely anonymous without the help of built-in functions that help define and format them in a way that is not only meaningful but also useful during development and testing.
__dir__(self) When a user wants to know the attributes of an object, they are likely to call
dir(...) function on the object. Then it calls the translator
__dir__ method of this object.
__len__(self) It is applicable when you have an object that contains a number of items. Herewith we can call the method
len(my_object) on the object.
__repr__(self) This method is called when the compiler wants to unambiguously define an object for debugging and development. This value is usually enclosed in angle brackets
< . . . >.
__str__(self) It aims to make the object human-readable. If this method is used in conjunction
__repr__ In a category, value
__str__ The method takes precedence.
__sizeof__(self) Helps determine the size of an object in bytes.
These functions are called when the compiler encounters the equal sign between two variables. These include:
__eq__(self, x) When we compare whether two variables are equal in value, the interpreter runs this method to get a result.
__gt__(self, x) Intuitively, this stands for “greater than” and is called when the symbol is greater than the arithmetic
> It is located between two variables. It is usually used between two numeric variables, but can also be used to compare variables with other types.
__ge__(self, x) This means “greater than or equal to” and is called when the arithmetic symbol is greater than or equal to
>= It is located between two variables.
__lt__(self, x) Intuitively, this stands for “less than” and is called when the symbol is greater than the arithmetic
< It is located between two variables.
__le__(self, x) This means “less than or equal to” and is called when the arithmetic symbol is greater than or equal to
<= It is located between two variables.
The most characteristic of numbers are arithmetic operations. We can make our objects display the same behaviors that numbers do and respond to arithmetic symbols as numbers do, simply by implementing one or two of the special methods listed below.
__add__(self, x) This method is called by the Python interpreter when a “+” sign is encountered between two variables.
__mul__(self, x) For arithmetic multiplication, the compiler calls this special implicitly.
__sub__(self, x) To give our object the ability to subtract from it, we can add this method.
Real World Example #1: More Pythonic temperature class
First, let’s define a simple class that holds a given room temperature.
When we try to add a value to an instance of our temperature class, we get an error.
>>> Temperature(30, 'C') + 1TypeError: unsupported operand type(s) for +: 'Temperature' and 'int'
Now, let’s extend a class and give it the ability to perform arithmetic operations by executing
Now, let’s see the result after we add the custom
__add__ method for our temperature class.
>>> Temperature(30, 'C') + 6
<Temperature: 36°C>>>> Temperature(30, 'C') + Temperature(35.6, 'F')
<Temperature: 38°C>>>> Temperature(34, 'C') + Temperature(66, 'C')
Iterators: lists, groups, strings, groups
__contains__(self, x) This is used when
in The keyword is used to check if the element exists in the iterator (eg:
x in ["a", "b"])
__delitem__(self, key) When an item is deleted from the iterable via
del keyword, this method is triggered (eg
__getitem__(self, key) This method is called by the interpreter when the conductor syntax is used on a variable (eg:
iter The method used in generator expressions, to produce one element of the array at a time.
__next__(self) can be used with
__iter__ To make any object iterable. once a pair
__next__ present in any class, the object will respond to it
for i in my_object syntax.
__setitem__(self, key, newvalue) The compiler uses this method to set the element to any specific position. You will notice that
tuples Does not support item mapping, as is Fixed.
Real-life Example #2: A more pythonic approach to Scrabble
Let’s bring to life everything we learned in this article with a simplified visualization of Scrabble. Our Scrabble game will use a number of magical techniques to make it interact with the interpreter in a more friendly manner.
There is no Scrabble game without letter tiles to play. The scrabble piece contains a letter in the alphabet and a number that indicates the points a player scores by playing each turn. In Scrabble, players often compare tiles to play which ones will score them the most points, so let’s support that in our design.
The tiles can then be declared and used in the game like this:
tile_a = Tile('A', 1)
tile_q = Tile('Q', 10)print(tile_a)
# A (1)print(tile_q)
# Q (10)print(tile_q > tile_a)
Next, we’ll define the squares on the Scrabble board. We know that there are 255 squares in the board. Some of these cells award special points to players who play a role on them. Our cells will keep the following data:
word_multiplier. Since we also have a single instance of cells during a full game, we must make them single to prevent multiple creations of a single cell on the board.
Finally, we’ll select our board. All moves will be played on the board from the start of the game. We will order one board for a full game session, We will do this singleton Class.
When a Scrabble player makes a move, he places several vertical or horizontal squares to form a word. To represent this in code, we can keep a set of boxes and the cells they run on. Players are also constantly evaluating potential moves to determine which will give them the highest points.
Now, when a player wants to compare two moves to see which one will be more useful, we can elegantly compare the moves as we do with primes, chains, etc.
move_one = Move([
[tile_a, cell_1], [tile_c, cell_2], [tile_e, cell3]
# ACE = 5move_two = Move([
[tile_z, cell_1], [tile_o, cell_2], [tile_o, cell3]
# ZOO = 12print(move_one > move_two)
# Falseprint(move_one < move_two)
Large Python projects would definitely be much easier to work with, if they accepted most of their components and responded to a lot of the syntax we’re used to with native types – we see this in the Django ORM, with the ability to iterate much more