Отсутствует магический метод возведения в степень в Python

#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, вы в основном дали ответ, если вы хотите переформатировать оба ваших комментария в ответ, я приму его.