Ich habe Code, der in Python 3.6 funktioniert hat und in Python 3.8 fehlschlägt. Es scheint sich darauf zu beschränken, die super
Unterklasse wie folgt aufzurufen 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
Der Zweck dieses super(object, self).__repr__
Aufrufs besteht darin, den Standard zu verwenden, '<__main__.Test object at 0x7fa109953cf8>'
__repr__
anstatt den gesamten Inhalt der Tupelelemente auszudrucken (was standardmäßig der Fall wäre). Es gibt einige Fragen zusuper
, was zu ähnlichen Fehlern , aber sie:
- Siehe die parameterlose Version
super()
- Fehler bereits in Python 3.6 (es hat bei mir vor 3.6 funktioniert -> 3.8 Upgrade)
- Ich verstehe sowieso nicht, wie ich das beheben kann, da es sich nicht um eine benutzerdefinierte Metaklasse handelt, über die ich die Kontrolle habe, sondern um die von stdlib bereitgestellte
typing.NamedTuple
.
Meine Frage ist, wie ich dies beheben kann, während die Abwärtskompatibilität mit Python 3.6 erhalten bleibt (ansonsten würde ich nur verwenden @dataclasses.dataclass
anstatt von zu erben typing.NamedTuple
).
Eine Nebenfrage ist, wie dies zum Zeitpunkt der Definition fehlschlagen kann , da sich der fehlerhafte super
Aufruf in einer Methode befindet, die noch nicht einmal ausgeführt wurde. Zum Beispiel:
In [3]: class Test(typing.NamedTuple):
...: a: int
...: b: float
...: def __repr__(self):
...: return foo
funktioniert (bis wir das tatsächlich aufrufen __repr__
), obwohl foo
es sich um eine undefinierte Referenz handelt. Ist super
diesbezüglich magisch?
__repr__ = object.__repr__
in Ihrer Klassendefinition funktioniert für mich unter Python3.6 und Python3.8
typing.NamedTuple
. typing.NamedTupleMeta
, das macht ein paar Spielereien. super()
muss __class__
zur Kompilierungszeit verfügbar sein , was hier anscheinend nicht der Fall ist. Siehe auch: Geben Sie ein __classcell__
Beispiel für die Python 3.6-Metaklasse
super
Objekts selbst, keine Darstellung IhrerTest
Instanz.