Могут ли магические методы возвращать другой тип результата?

#python #magic-methods

Вопрос:

Может ли волшебный метод, подобный def __sub__() тому, который работает с типом, возвращать другой тип результата?

Например, в пользовательском классе ниже -1 оператор возвращает строку. Требование состоит в том, что если есть разница, верните строку, показывающую представление разницы.

 import copy class User:  def __init__(self, username=""):  self.__user_name = username    def __sub__(self,other):  if other.__user_name != self.__user_name:  return "User name changed from {} to {}".format(self.__user_name,  other.__user_name);  else:  return ""    def set_user_name(self, username):  self.__user_name = username     user_1 = User("John") user_2 = copy.copy(user_1) user_2.set_user_name("Tom") user_diff = user_1 - user_2  

После чего, если мы напечатаем user_diff , это будет «Имя пользователя изменено с Джона на Тома» .

Разрешено ли это и является ли это одним из способов показать разницу, главным образом» -«, возвращающим другой тип объекта (строку) по сравнению с User ?

Комментарии:

1. Да, они могут, например, если у вас есть __sub__ от одного Point к другому Point , результат должен быть Vector не другим Point . Есть много случаев использования, когда имеет смысл делать подобные вещи.

2. Вы можете, но я не уверен, что согласен с таким использованием. Хотя это и не требуется , вы должны сохранять «ожидаемое» поведение в своих операциях, где это возможно. Например, (user_1 - user_2) user_2 == user_1 было бы неплохо. Если вы слишком далеко отошли от традиционного значения оператора, лучше вместо этого использовать новый метод. user_1.change_from(user_2) например.

Ответ №1:

Конечно: ярким примером в стандартной библиотеке является datetime.__sub__ , который возвращает timedelta экземпляр, когда другой операнд является другим datetime экземпляром.

 gt;gt;gt; d1 = datetime.datetime.now() gt;gt;gt; d2 = datetime.datetime.now() gt;gt;gt; type(d2 - d1) lt;class 'datetime.timedelta'gt;