@ Ответ Nullman работает, потому что их решение на самом деле изменяет объект класса toy
, который t
является экземпляром, а не самим экземпляром, как ваш подход.
Специальный атрибут __class__
ссылается на объект класса, к которому принадлежит экземпляр.
print(t.__class__ is toy) # True
Итак, t.__class__.__repr__ = my_custom_repr
присваивает __repr__
классу toy
, а не экземпляру t
.
Это становится видимым при сравнении вывода print(t.__repr__)
между вашим подходом и подходом Нулмана.Предполагая, что функция уровня модуля __repr__
выглядит следующим образом:
def __repr__(self):
return repr(self.__class__)
Ваше решение показывает:
<bound method __repr__ of <__main__.toy object at 0x00000000029E5A90>>
Обратите внимание, оно говорит __main__.toy object
.
Решение Nullman показываетэто как:
<bound method __repr__ of <class '__main__.toy'>>
Когда вы вызываете t.__repr__()
, используя свой подход, вы вызываете метод, который вы установили для экземпляра t
, следовательно, он возвращает то, что вы сделали, он перенастроил;строка Success
в вашем примере.
При использовании repr()
, однако, class определяет вывод:
Класс можетуправляйте тем, что эта функция возвращает для своих экземпляров, определяя метод __repr__()
.
Как справедливо заметил Наллман, их подход изменит поведение всех существующих и будущих объектов,создается из toy
.
Что касается странного имени, которое назначенный метод показывает при использовании вашего кода:
<bound method inhtoy.__new__.<locals>.__repr__ of <__main__.toy object at 0x7f76e0b61f98>>
... это квалифицированное имя объекта функции, полученное из специального атрибута __qualname__
.Это функция __repr__
из локальной области видимости метода вашего класса inhtoy
__new__
.
Кстати, прохождение вашего экземпляра inst
через магический метод __new__
вашего inhtoy
классане очень многого достиг.Ваш код функционально эквивалентен:
def __repr__(self):
return "Success"
inst.__repr__ = types.MethodType(__repr__, obj)