Почему str () не использует __getattribute__ для получения __str__ и как создать эффект? - PullRequest
3 голосов
/ 20 апреля 2020

Когда я вызываю str() для объекта, у которого есть перегруженный метод __getattribute__, он, кажется, не использует его, а вместо этого вызывает __str__ напрямую. Есть ли какая-то другая функциональность, которую я должен изменить, или способ заставить ее использовать __getattribute__? Если я перегрузлю __str__ напрямую, он будет работать как положено, но это не идеально для моих нужд.

class A(object):
    def __getattribute__(self, attr):
        if attr == "__str__":
            return lambda: "Hello"
        return object.__getattribute__(self, attr)

x = A()

print(x)
print(str(x))
print(x.__str__())

Вывод: <<strong> main .A объект по адресу 0x000001FDF7AEA760> <<strong> main .A объект по адресу 0x000001FDF7AEA760> Привет

Ожидаемый результат: Привет Привет Привет

1 Ответ

5 голосов
/ 20 апреля 2020

Да, это задокументированное поведение :

Этот метод все еще можно обойти при поиске специальных методов в результате неявного вызова через синтаксис языка или встроенные функции .

И здесь :

Для пользовательских классов неявные вызовы специальных методов гарантированно будут работать правильно, только если они определены для типа объекта, не в словаре экземпляров объекта

...

В дополнение к обходу любых атрибутов экземпляра в интересах корректности, неявный поиск специальных методов обычно также обходит метод __getattribute__() даже объекта метакласс ...

...

Что касается почему :

В обход механизма __getattribute__() таким способом обеспечивает значительные возможности для оптимизации скорости в интерпретаторе за счет некоторой гибкости в обработке специальных методов (специальный метод должен быть установлен на самом объекте класса в порядке должен постоянно вызываться переводчиком).

...