Last modified April 8, 2025
This comprehensive guide explores Python's __isub__ method, the
special method for in-place subtraction. We'll cover basic usage, operator
overloading, mutable vs immutable types, and practical examples.
The __isub__ method implements the in-place subtraction operation
(-=). It modifies the object's value without creating a new object.
Key characteristics: it should modify and return self, is called
when -= is used, and typically provides better performance than
regular subtraction for mutable objects.
Here's a simple implementation showing how __isub__ works with a
custom class. The method modifies the instance in place.
class Counter:
def __init__(self, value):
self.value = value
def __isub__(self, other):
self.value -= other
return self
def __repr__(self):
return f"Counter({self.value})"
c = Counter(10)
c -= 3
print(c) # Counter(7)
This example shows a simple counter class that implements in-place subtraction.
When -= is used, __isub__ modifies the instance's
value and returns self.
The method must return self to work correctly with chained
operations and to match Python's expected behavior for in-place operations.
For mutable objects, __isub__ can provide significant performance
benefits by avoiding the creation of new objects during subtraction.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __isub__(self, other):
self.x -= other.x
self.y -= other.y
return self
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(5, 7)
v2 = Vector(2, 3)
v1 -= v2
print(v1) # Vector(3, 4)
This vector class implements in-place vector subtraction. The operation modifies the original vector instead of creating a new one, which is more efficient.
For large objects or frequent operations, this can significantly reduce memory usage and improve performance compared to regular subtraction.
Immutable objects can't be modified in place, so their __isub__
typically returns a new object, similar to regular subtraction.
class ImmutablePoint:
def __init__(self, x, y):
self._x = x
self._y = y
@property
def x(self):
return self._x
@property
def y(self):
return self._y
def __isub__(self, other):
return ImmutablePoint(self.x - other, self.y - other)
def __repr__(self):
return f"Point({self.x}, {self.y})"
p = ImmutablePoint(8, 6)
p -= 2
print(p) # Point(6, 4)
This immutable point class returns a new instance when __isub__ is
called. The original object remains unchanged, maintaining immutability.
Note that for immutable objects, a -= b behaves the same as
a = a - b, just with potentially different implementation details.
__isub__ can handle operations with different types, providing
flexible in-place subtraction behavior.
class Measurement:
def __init__(self, value, unit='m'):
self.value = value
self.unit = unit
def __isub__(self, other):
if isinstance(other, (int, float)):
return Measurement(self.value - other, self.unit)
elif isinstance(other, Measurement):
if self.unit == other.unit:
return Measurement(self.value - other.value, self.unit)
raise ValueError("Units must match")
raise TypeError("Unsupported type")
def __repr__(self):
return f"{self.value}{self.unit}"
m = Measurement(10)
m -= 2.5
print(m) # 7.5m
This measurement class handles subtraction with both numbers and other measurements. It includes unit checking when subtracting measurements.
The implementation shows how to make __isub__ work with multiple
types while maintaining proper error checking and type safety.
Python's built-in types like lists implement __isub__ for
in-place operations. Here's how it works with lists.
numbers = [1, 2, 3, 4, 5]
numbers -= [3, 4] # Equivalent to numbers.extend([3, 4])
print(numbers) # [1, 2, 3, 4, 5, 3, 4]
# For sets, -= performs difference_update
s = {1, 2, 3, 4, 5}
s -= {3, 4}
print(s) # {1, 2, 5}
For lists, -= performs an extend operation (which might be
surprising). For sets, it performs a difference update, removing elements.
This demonstrates how different built-in types implement __isub__
differently based on their semantics. Always check the type's documentation.
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.