#python #python-3.x
#python #python-3.x
Вопрос:
Я определяю кучу методов числовой магии в пользовательском классе и обнаружил пробел, который я не могу объяснить, связанный с pow()
/ возведением в степень.
__pow__(self, other, modulo=None)
вызывается, когда ваш пользовательский класс является первым / крайним левым операндом.
__rpow__(self, other, modulo=None)
вызывается, когда ваш пользовательский класс является вторым операндом.
Я нашел случай, когда ни то, ни другое не вызывается, и я этого не понимаю. Вот пример случая, который просто возвращает имя вызываемого метода:
class Power:
def __pow__(self, other, modulo=None):
return '__pow__'
def __rpow__(self, other, modulo=None):
return '__rpow__'
>>> x = Power()
>>> pow(x, 5)
'__pow__'
>>> pow(5, x)
'__rpow__'
Пока все выглядит правильно. Но посмотрите, что происходит, когда вы используете необязательный аргумент modulo:
>>> pow(x, x, 5)
'__pow__'
>>> pow(5, x, 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for pow(): 'int', 'Power', 'int'
tl;dr, похоже __rpow__
, не вызывается при использовании аргумента modulo . Что дает?
Комментарии:
1. Я почти уверен, что это задокументировано. Для Python нет простого способа заставить это работать с 3 операндами. docs.python.org/3/reference/datamodel.html#object.__rpow __
2. @blubberdiblub Спасибо за ссылку! Мне неясно, что вызывается в этом случае. Это просто переход прямо к реализации C без возможности ее переопределения?
3. Ну, в этом случае он должен вызывать
__pow__()
первый операнд, который равенint
5. Так что да, он должен переходить к встроенной реализацииpow
for numbers . Тогда второй операнд, вероятно, должен быть совместим сint
,float
илиcomplex
. Для простоты, вероятно, лучше игнорировать третий операндpow
, если только вы не пишете критичный для производительности код для криптографии или математики, для чего, если я не ошибаюсь, был разработан этот третий операнд в особом случае. Но тогда у вас все равно есть специальное приложение.4. Спасибо @blubberdiblub. FWIW, вы в основном дали ответ, если вы хотите переформатировать оба ваших комментария в ответ, я приму его.