Complete guide to Python's __pow__ method covering power operations, operator overloading, and mathematical customization.
Last modified April 8, 2025
This comprehensive guide explores Python’s pow method, the special method that implements power/exponentiation operations. We’ll cover basic usage, three-argument form, mathematical customization, and examples.
The pow method is called to implement the power/exponentiation operation (** operator). It allows objects to define their own behavior for the power operation.
Key characteristics: it takes at least two arguments (self and exponent), can accept an optional third argument for modulus, and should return the result of the power operation. It’s part of Python’s operator overloading system.
Here’s a simple implementation showing how pow works with the ** operator. This example creates a number wrapper class.
basic_pow.py
class PowerNumber: def init(self, value): self.value = value
def __pow__(self, exponent):
print("__pow__ called")
return self.value ** exponent
num = PowerNumber(3) result = num ** 4 # Calls pow print(result) # Output: 81
This example shows the basic power operation. When ** is used with a PowerNumber instance, Python calls pow with the exponent.
The method returns the result of raising the stored value to the given power. This allows custom power behavior for user-defined objects.
pow can also implement the three-argument form of pow() which includes a modulus parameter for modular exponentiation.
three_arg_pow.py
class ModularNumber: def init(self, value): self.value = value
def __pow__(self, exponent, modulus=None):
print("__pow__ called with modulus" if modulus else "__pow__ called")
if modulus is not None:
return pow(self.value, exponent, modulus)
return self.value ** exponent
num = ModularNumber(5) print(num ** 3) # 125 print(pow(num, 3, 7)) # 6 (125 % 7)
This implementation handles both two-argument and three-argument power operations. The modulus parameter is optional and defaults to None.
When using the built-in pow() with three arguments, Python calls pow with the modulus parameter. This enables efficient modular exponentiation.
When the left operand doesn’t support power operation, Python checks for rpow on the right operand. This is called “reflected power”.
reverse_pow.py
class ReversePower: def rpow(self, base): print("rpow called") return base ** 2 # Always squares the base
rp = ReversePower() result = 5 ** rp # Calls rpow print(result) # 25
This example shows how rpow is called when the left operand (5 in this case) doesn’t know how to handle power operations with our class.
The method receives the base as its first argument and returns the result of the operation. This enables power operations with built-in types on the left.
pow can implement matrix exponentiation, where a matrix is raised to an integer power through repeated multiplication.
matrix_pow.py
class Matrix: def init(self, data): self.data = data
def __mul__(self, other):
# Simple matrix multiplication (for illustration)
return Matrix([[sum(a*b for a,b in zip(row, col))
for col in zip(*other.data)]
for row in self.data])
def __pow__(self, exponent):
if not isinstance(exponent, int) or exponent < 0:
raise ValueError("Exponent must be non-negative integer")
result = Matrix([[1 if i == j else 0 for j in range(len(self.data))]
for i in range(len(self.data))]) # Identity matrix
for _ in range(exponent):
result = result * self
return result
def __repr__(self):
return str(self.data)
m = Matrix([[1, 2], [3, 4]]) print(m ** 2) # [[7, 10], [15, 22]]
This matrix class implements exponentiation through repeated multiplication. The pow method checks for valid exponents and uses the identity matrix as the starting point.
Matrix exponentiation is useful in many mathematical and scientific computing applications, particularly for linear transformations.
pow can define non-standard power operations, like element-wise exponentiation for container classes or other mathematical operations.
custom_pow.py
class Vector: def init(self, values): self.values = values
def __pow__(self, exponent):
if isinstance(exponent, (int, float)):
return Vector([x ** exponent for x in self.values])
elif isinstance(exponent, Vector):
return Vector([x ** y for x, y in zip(self.values, exponent.values)])
else:
raise TypeError("Unsupported exponent type")
def __repr__(self):
return f"Vector({self.values})"
v1 = Vector([2, 3, 4]) print(v1 ** 2) # Vector([4, 9, 16]) print(v1 ** Vector([1, 2, 3])) # Vector([2, 9, 64])
This Vector class implements element-wise exponentiation. It handles both scalar exponents (applied to each element) and vector exponents (element-wise).
The method includes type checking to ensure the exponent is either a number or another Vector, raising TypeError for unsupported types.
Handle different exponent types: Check exponent types for safety
Implement rpow when needed: For operations with built-ins on left
Consider three-argument form: Support modular exponentiation if relevant
Document behavior: Clearly document any special power rules
Raise appropriate exceptions: For invalid exponents or operations
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.