Exploring Python Magic Method Operators
Magic methods, also known as Dunder methods, are special Python methods that start and end with two underscores. They reference particular behaviors for specific actions or operations. Magic methods are automatically invoked when certain operations (such as arithmetic or comparison operators) are performed on class instances.
One of the critical benefits of magic methods is their ability to enable operator overloading. Operator overloading is the ability to reference multiple methods with the same name but different parameters. This can be used to extend existing operators' functionality and create more intuitive and expressive code.
This article will discuss Python magic methods for building a shopping cart class object. We will use magic methods to define custom behaviors for the following operations:
- Initializing a cart
- Adding items to a cart
- Removing items from a cart
- Calculating the total price of items in a cart
- Viewing the list of items in a cart
- Adding carts together
Construct, initialize, and destroy the ShoppingCart
These basic operators initialize, construct, or destroy objects in Python code. They are automatically invoked when an object is created or destroyed. The `__new__` method creates a new class iterable, the `__init__` method is used to initialize it, and the `__del__` method is used to destroy it.
Let's see how they are used to build the ShoppingCart class:
Let's create an instance of the class and see how this works:
Initializing the ShoppingCart
The ShoppingCart Number is: 1
We created the `ShoppingCart` custom class in the above code snippet. When an instance of this custom class is created, the items list and cart number are initialized in the `__init__` magic method.
The class instance was first created before the initialization with the `__init__` method. It is implicit. We can, however, make the step explicit with the `__new__` method:
Creating a new instance of the Shopping
CartInitializing the ShoppingCart
The ShoppingCart Number is:1
When we introduced the __new__ method, we noticed when a new class instance was created. The __new__ method then calls the __init__ method to initialize the created ShoppingCart.
After creating an instance of the class, we may want to delete it. We can do so with the del keyword:
If we try to call `cart1`, we get a `NameError` with the message name `cart1` that is not defined. We can check to see if the number of carts has decreased by 1:
1
We can see that we still maintain the same number of carts despite deleting `cart1`. The `del` keyword implicitly calls the `__del__` magic method to delete `cart1`. We can customize this operation also to decrease the number of carts for every delete operation:
Initializing the ShoppingCart
The ShoppingCart Number is: 1
Deleting ShoppingCart Number1
Now the number of carts should decrease by 1 when a cart is deleted:
0
Add and remove items from the ShoppingCart
The `add_item` and `remove_item` methods are used to add and remove items from the cart:
An item has a `name` and `price`. To be able to add an item, we will create the `Item` class with these attributes:
Suppose we are buying two shirts, a pair of jeans and shoes. Let's create and add these items to the cart:
Initializing the ShoppingCart
<__main__.Item object at 0x000001D86BF43580> has been added
<__main__.Item object at 0x000001D86BF43AC0> has been added
<__main__.Item object at 0x000001D86BF43520> has been added
<__main__.Item object at 0x000001D86BF43EE0> has been added
We realize that we may not require two shirts. So we want to remove one of them from the cart:
<__main__.Item object at 0x000001D86BF43AC0> has been removed
Wait a minute; the items we added and removed were not printed in a human-readable format. Why so? The next section will see how to print using Python magic methods.
Print from the Item and ShoppingCart class objects
When we tried to print the items added to `cart1`, we got the memory address of these items. It is difficult to read and understand what was printed. The `__repr__` and `__str__` methods can help us with strings. The `__repr__` method is used to return a string representation that is intended for programmers. In contrast, the `__str__` method returns a string representation designed for users.
The `__repr__` method returns a string representation of an object that can be used to recreate the object. It means the string should be unambiguous and contain all the information necessary to reconstruct the object. The `__str__` method, on the other hand, can return a more human-readable string representation of an object. This string does not need to be unambiguous or contain all the information about the object. It can be used to display the object to a user.
We can now move forward to process the items in the list; we will use the string representation `__repr__` method:
Let's delete `cart1` and confirm that we no longer have any cart instances:
Deleting ShoppingCart Number 1
0
Next, let's create a new cart and add the items to it:
Initializing the ShoppingCart
Item('Shirt', 20) has been added
Item('Shirt', 20) has been added
Item('Shoe', 50) has been added
Item('Jeans', 25) has been added
We've mentioned that the `__repr__` method can recreate the original object. Let's see how this is done:
"Item('Shoe', 50)"
'str'
Item('Shoe', 50)
'Item'
('Shoe', 50)
Deleting ShoppingCart Number1
The `__repr__` method can recreate the original object with the `eval` function. You can't do it with the `__str__` built-in function.
Now, let's use the `__str__` method to display a user-friendly message of the items and the `__len__` method to get the number of items in the cart:
Next, let's create the cart and add the items to it:
Initializing the ShoppingCart
Item('Shirt', 20) has been added
Item('Shirt', 20) has been added
Item('Shoe', 50) has been added
Item('Jeans', 25) has been added
The item(s) in the ShoppingCarts:
A Shirt that cost $20
A Shirt that cost $20
A Shoe that cost $50
A Jeans that cost $25
Item('Shirt', 20) has been removed
The number of items in the cart is: 3
Deleting ShoppingCart Number1
More magic methods
We can use other class method objects in the `ShoppingCart`. Suppose you've made an entry with the wrong price, you can make the price correction by implementing the `__setitem__` magic method. What if you have two carts and want to combine the items in one of the carts before checkout? Use the `__iadd__` magic method:
Let's see how this work by creating two carts. The first cart contains two shirts, a shoe, and a pair of jeans. The second cart includes a pair of headphones:
Initializing the ShoppingCart
Item('Shirt', 20) has been added
Item('Shirt', 20) has been added
Item('Shoe', 50) has been added
Item('Jeans', 25) has been added
Initializing the ShoppingCart
Item('Headphone', 20) has been added
We added a headphone costing 20 in cart2. We want 40 pairs of headphones instead. We correct as follows:
The item(s) in the ShoppingCarts:
A Headphone that cost $40
Next, we added items in cart2 to cart1:
The item(s) in the ShoppingCarts:
A Shirt that cost $20
A Shirt that cost $20
A Shoe that cost $50
A Jeans that cost $25
A Headphone that cost $40
Next, we checkout to get the total price of all the items in our cart:
Checkout completed. Total price: $155
After adding the contents in cart2 to cart1, cart2 is now empty. We can then delete this cart:
[]
Deleting ShoppingCart Number2
1
Conclusion
Python magic methods are a fantastic way to create flexible and expressive code that meets your needs. With these tools, you can customize your classes' behavior to perform exactly how you want. If you want to improve your Python programming skills, learning and utilizing these powerful concepts is essential.
In this article, we've explored the world of Python magic methods and learned how to construct a dynamic shopping cart. We've used a range of built-in Python functions to add and remove items, present cart contents in a user-friendly format, merge items from multiple carts and calculate the total price during checkout. The result is a highly adaptable, feature-rich shopping cart that can be customized to meet your unique requirements.
For further practice with Python magic methods and object-oriented programming, consider exploring the projects available in our Python track collections: Introduction to Python, Python Core, and more. You'll discover many engaging projects that align with your interests and aspirations. Embrace the enchanting power of Python code, unleash your boundless creativity, and allow this programming language to empower you in crafting truly awe-inspiring applications.
Related Hyperskill Topics
like this