Python Magic Methods with Stock Sorting

Python Magic Methods with a Stock Sorting Example

Python magic methods, also known as “dunder” methods (short for “double underscore”), allow us to define how custom objects behave in specific situations. Two of the most commonly used magic methods are __str__ and __lt__. In this blog, we’ll explore how these methods can be used to sort stock and bond objects, giving them custom behaviors for string representation and comparison.

Magic Methods in Focus:

  • __str__: This method is called when you use the str() function on an object, or when you print the object. It returns the string representation of an object, which should be human-readable.

  • __lt__: Short for “less than”, this method defines how two objects should be compared when using the < operator. It’s essential for sorting objects, as it allows Python to know how to order them based on specific attributes.

Problem Scenario: Sorting Stocks and Bonds

Suppose we have two types of financial instruments: stocks and bonds. Each has attributes that define them. For stocks, the key attribute is price, while for bonds, it’s the yield_amount. We want to sort a list of these instruments based on these attributes, but we need a custom behavior for both string representation and comparison.

Implementing the Solution

We’ll create two classes, Stock and Bond, each inheriting from a common base class, FinancialInstrument. We’ll override the __str__ and __lt__ methods in each class.

				
					class FinancialInstrument:
    def __init__(self, name):
        self.name = name

class Stock(FinancialInstrument):
    def __init__(self, name, price):
        super().__init__(name)
        self.price = price

    def __str__(self):
        return f"Stock: {self.name}, Price: {self.price}"

    def __lt__(self, other):
        if isinstance(other, Stock):
            return self.price < other.price
        return NotImplemented

class Bond(FinancialInstrument):
    def __init__(self, name, yield_amount):
        super().__init__(name)
        self.yield_amount = yield_amount

    def __str__(self):
        return f"Bond: {self.name}, Yield: {self.yield_amount}"

    def __lt__(self, other):
        if isinstance(other, Bond):
            return self.yield_amount < other.yield_amount
        return NotImplemented

				
			

How It Works:

  • The __str__ method in both the Stock and Bond classes returns a nicely formatted string with the instrument’s name and its key attribute (price for stocks and yield for bonds).

  • The __lt__ method compares Stock objects by price and Bond objects by yield. When we try to sort a list of stocks or bonds, Python will use the __lt__ method to determine the order.

Example

Let’s create a list of Stock and Bond objects and sort them:

				
					# Create a list of stock and bond objects
stocks = [
    Stock("Apple", 150),
    Stock("Tesla", 1200),
    Stock("Microsoft", 300)
]

bonds = [
    Bond("US Treasury", 2.5),
    Bond("Corporate Bond", 3.8),
    Bond("Municipal Bond", 1.7)
]

# Sort the lists
sorted_stocks = sorted(stocks)
sorted_bonds = sorted(bonds)

# Print the sorted lists
print("Sorted Stocks:")
for stock in sorted_stocks:
    print(stock)

print("\nSorted Bonds:")
for bond in sorted_bonds:
    print(bond)

				
			

Output:

				
					Sorted Stocks:
Stock: Apple, Price: 150
Stock: Microsoft, Price: 300
Stock: Tesla, Price: 1200

Sorted Bonds:
Bond: Municipal Bond, Yield: 1.7
Bond: US Treasury, Yield: 2.5
Bond: Corporate Bond, Yield: 3.8

				
			

Breaking Down the Solution:

  • The sorted() function calls the __lt__ method to compare each pair of objects. For stocks, it compares the price attribute, and for bonds, it compares the yield_amount attribute.
  • The __str__ method is called automatically when printing the objects, so we get a nicely formatted output.

Conclusion:

Using magic methods like __str__ and __lt__ allows us to customize the behavior of our Python objects in powerful ways. In this example, we customized the string representation and comparison logic for sorting stocks and bonds. These methods make our objects more intuitive and Pythonic, allowing us to leverage Python’s built-in functions like sorted() seamlessly.

Official Python Documentation: Data Model (Magic Methods)

This link takes readers to Python’s official documentation, where they can explore more about magic methods and how they can be used to customize class behavior.