У меня есть код, который работал в Python 3.6 и не работает в Python 3.8. Кажется, все сводится к вызову super
в подклассе typing.NamedTuple
, как показано ниже:
<ipython-input-2-fea20b0178f3> in <module>
----> 1 class Test(typing.NamedTuple):
2 a: int
3 b: float
4 def __repr__(self):
5 return super(object, self).__repr__()
RuntimeError: __class__ not set defining 'Test' as <class '__main__.Test'>. Was __classcell__ propagated to type.__new__?
In [3]: class Test(typing.NamedTuple):
...: a: int
...: b: float
...: #def __repr__(self):
...: # return super(object, self).__repr__()
...:
>>> # works
Цель этого вызова super(object, self).__repr__
состоит в использовании стандартного '<__main__.Test object at 0x7fa109953cf8>'
__repr__
вместо распечатки всего содержимого элементов кортежа (что будет по умолчанию). Есть некоторые вопросы на super
, приводящие к аналогичным ошибкам, но они:
- См. Версию без параметров
super()
- Ошибка уже в Python 3.6 (у меня она работала до обновления 3.6 -> 3.8)
- В любом случае я не понимаю, как это исправить, учитывая, что я управляю не пользовательским метаклассом, а Предоставляется stdlib
typing.NamedTuple
.
Мой вопрос: как это исправить, поддерживая обратную совместимость с Python 3.6 (в противном случае я бы просто использовал @dataclasses.dataclass
вместо наследования от typing.NamedTuple
)?
Дополнительный вопрос: как это может произойти во время определения , учитывая, что вызывающий вызов super
вызов находится внутри метода, который еще даже не выполнен. Например:
In [3]: class Test(typing.NamedTuple):
...: a: int
...: b: float
...: def __repr__(self):
...: return foo
работает (пока мы фактически не назовем __repr__
), хотя foo
является неопределенной ссылкой. super
волшебно в этом отношении?