Я нашел похожие вопросы, но они довольно старые (6-8 лет) и могут быть устаревшими, и, кстати, в некоторых ответах нет объяснений.
Я написал следующий фрагмент кода Python-3, чтобы создать класс, который поддерживает хранение имен и безымянных полей так же, как вы можете иметь переменные с именованными и безымянными параметрами в вызове функции:
class struct(list):
def __init__(self, *args, **kwargs):
super().__init__(args)
for key, value in kwargs.items():
setattr(self, key, value)
def __repr__(self):
s = super().__repr__()[1:-1]
for key, val in self.__dict__.items():
s += ', '+key+'='+repr(val)
return 'struct('+s+')'
def __str__(self):
s = super().__str__()[1:-1]
print('Debug : super().__str__() = "'+super().__str__()+'"')
print('Debug : list(self).__str__() = "'+list(self).__str__()+'"')
print('Debug : s = "'+s+'"')
for key, val in self.__dict__.items():
s += ', '+key+'='+str(val)
return '{'+s+'}'
a = struct(1, 2, 3, a="akeja", b=21, c=True, d="lkj")
print('repr(a)="'+repr(a)+'"\n')
print('str(a)="'+str(a)+'"\n')
Выполнение этого кода в idle-3.5.2 даст следующий результат:
>>>
RESTART: struct.py
repr(a)="struct(1, 2, 3, b=21, d='lkj', a='akeja', c=True)"
Debug : super().__str__() = "struct(1, 2, 3, b=21, d='lkj', a='akeja', c=True)"
Debug : list(self).__str__() = "[1, 2, 3]"
Debug : s = "truct(1, 2, 3, b=21, d='lkj', a='akeja', c=True"
str(a)="{truct(1, 2, 3, b=21, d='lkj', a='akeja', c=True, b=21, d=lkj, a=akeja, c=True}"
>>>
В этом посте , @Sven Marnach подчеркнул необходимость использования list.__init__(self, args)
вместо super().__init__(args)
в методе __init__(...)
, но это ничего не меняет (на самом деле, он писал list.__init__(self, *args)
, но этот вообще не работает).
Однако, как можно видеть во вторых строках отладки, вызов super().__str__()
, который я ожидаю вернуть в результате вызова функции __str__
из моего суперкласса (list
), фактически будет вернуть то, что очень похоже на ожидаемое возвращение от self.__repr__()
Я не могу понять, почему self.__repr__()
, кажется, вызывается вместо list(self).__str__()
. Должен ли я напрямую позвонить __str__()
с list(self)
, как в @Sven Marnach 6лет. совет ? Это правильный способ сделать? Зачем ? Или это просто ошибка, о которой я должен сообщить?