Syntax
object.__rpow__(self, other)
The Python __rpow__()
method implements the reverse exponentiation operation that is exponentiation with reflected, swapped operands. So, when you call x ** y
, Python attempts to call x.__pow__(y)
. Only if the method is not implemented on the left operand, Python attempts to call __rpow__
on the right operand and if this isn’t implemented either, it raises a TypeError
.
We call this a “Dunder Method” for “Double Underscore Method” (also called “magic method”). To get a list of all dunder methods with explanation, check out our dunder cheat sheet article on this blog.
Python __pow__ vs __rpow__
Say, you want to calculate the **
operation on two custom objects x
and y
:
print(x ** y)
Python first tries to call the left object’s __pow__()
method x.__pow__(y)
. But this may fail for two reasons:
- The method
x.__pow__()
is not implemented in the first place, or - The method
x.__pow__()
is implemented but returns aNotImplemented
value indicating that the data types are incompatible.
If this fails, Python tries to fix it by calling the y.__rpow__()
for reverse exponentiation on the right operand y
.
If the reverse exponentiation method is implemented, Python knows that it doesn’t run into a potential problem of a non-commutative operation. If it would just execute y.__pow__(x)
instead of x.__pow__(y)
, the result would be wrong because the operation may be non-commutative when defined as a custom operation. That’s why y.__rpow__(x)
is needed.
So, the difference between x.__pow__(y)
and x.__rpow__(y)
is that the former calculates x ** y
whereas the latter calculates y ** x
— both calling the respective method defined on the object x
.
You can see this in effect here where we attempt to call the operation on the left operand x
—but as it’s not implemented, Python simply calls the reverse operation on the right operand y
.
class Data_1: pass class Data_2: def __rpow__(self, other): return 'called reverse **' x = Data_1() y = Data_2() print(x ** y) # called reverse **
Note that the __rpow__
and __pow__
methods also define the built-in pow()
function. So, if you call pow()
after executing the previous code snippet, you obtain the same result:
print(pow(x, y)) # called reverse **
Related Video Exponentiation
References: