Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Emulating Numeric Types in Python
Python includes built-in mathematical data structures like complex numbers, floating-point numbers, and integers. But occasionally we might want to develop our own custom-behaved number classes. Here, the idea of imitating number classes is put into use. We can create objects that can be used in the same way as native numeric classes by simulating them using special methods (also called "magic methods" or "dunder methods").
Basic Addition with __add__
The simplest way to emulate numeric behavior is implementing the __add__ method ?
class MyNumber:
def __init__(self, value):
self.value = value
def __add__(self, other):
return MyNumber(self.value + other.value)
def __str__(self):
return str(self.value)
# Create instances and add them
a = MyNumber(2)
b = MyNumber(3)
result = a + b
print(result)
5
Here, we define a custom class MyNumber that stores a numeric value. The __add__ method is called when the + operator is used between two instances, returning a new MyNumber with the sum.
Comparison Operations with __eq__
To enable equality comparisons, implement the __eq__ method ?
class MyNumber:
def __init__(self, value):
self.value = value
def __eq__(self, other):
return self.value == other.value
def __str__(self):
return str(self.value)
# Test equality
a = MyNumber(2)
b = MyNumber(3)
c = MyNumber(2)
print(a == b) # Different values
print(a == c) # Same values
False True
The __eq__ method is called when the == operator is used, returning True if the values are equal and False otherwise.
Complete Fraction Implementation
Let's examine a more comprehensive example by creating a Fraction class that supports all basic arithmetic operations ?
class Fraction:
def __init__(self, numerator, denominator=1):
self.num = numerator
self.deno = denominator
def __str__(self):
if self.deno == 1:
return str(self.num)
else:
return "{}/{}".format(self.num, self.deno)
def __add__(self, other):
if isinstance(other, int):
other = Fraction(other)
common_deno = self.deno * other.deno
num = self.num * other.deno + other.num * self.deno
return Fraction(num, common_deno).simplify()
def __sub__(self, other):
if isinstance(other, int):
other = Fraction(other)
common_deno = self.deno * other.deno
num = self.num * other.deno - other.num * self.deno
return Fraction(num, common_deno).simplify()
def __mul__(self, other):
if isinstance(other, int):
other = Fraction(other)
num = self.num * other.num
deno = self.deno * other.deno
return Fraction(num, deno).simplify()
def __truediv__(self, other):
if isinstance(other, int):
other = Fraction(other)
num = self.num * other.deno
deno = self.deno * other.num
return Fraction(num, deno).simplify()
def gcd(self, a, b):
if b == 0:
return a
else:
return self.gcd(b, a % b)
def simplify(self):
divisor = self.gcd(abs(self.num), abs(self.deno))
num = self.num // divisor
deno = self.deno // divisor
if deno < 0:
num = -num
deno = -deno
return Fraction(num, deno)
# Create fraction objects and test operations
f1 = Fraction(2, 3)
f2 = Fraction(3, 4)
f3 = Fraction(1, 2)
print("Addition:", f1 + f2)
print("Subtraction:", f2 - f3)
print("Multiplication:", f1 * f3)
print("Division:", f1 / f2)
Addition: 17/12 Subtraction: 1/4 Multiplication: 1/3 Division: 8/9
Essential Magic Methods for Numeric Types
| Operation | Magic Method | Description |
|---|---|---|
| Addition (+) | __add__ |
Defines behavior for addition operator |
| Subtraction (-) | __sub__ |
Defines behavior for subtraction operator |
| Multiplication (*) | __mul__ |
Defines behavior for multiplication operator |
| Division (/) | __truediv__ |
Defines behavior for division operator |
| Equality (==) | __eq__ |
Defines behavior for equality comparison |
| String representation | __str__ |
Defines how object appears when printed |
Key Features of the Fraction Class
The Fraction class demonstrates several important concepts:
Automatic type conversion ? Integer operands are automatically converted to fractions
Fraction simplification ? Results are reduced to lowest terms using the GCD algorithm
Proper formatting ? Whole numbers display without denominators
Sign handling ? Negative signs are moved to the numerator for consistency
Common Applications
Specialized numerical types ? Creating custom number classes like fractions, complex numbers, or decimal types with specific precision
Domain-specific calculations ? Financial calculations requiring exact decimal arithmetic or scientific computations with units
Educational tools ? Teaching mathematical concepts through interactive number classes
Performance optimization ? Implementing more efficient algorithms for specific numeric operations
Conclusion
Emulating numeric types in Python through magic methods allows you to create custom number classes that behave like built-in types. By implementing methods like __add__, __sub__, and __eq__, you can define how your objects respond to arithmetic operations and comparisons, enabling natural mathematical syntax for specialized numeric types.
