gpt4 book ai didi

python - `super` 子类中的 `typing.NamedTuple` 在 python 3.8 中失败

转载 作者:行者123 更新时间:2023-12-03 15:08:58 32 4
gpt4 key购买 nike

我有在 Python 3.6 中工作但在 Python 3.8 中失败的代码。似乎可以归结为调用 supertyping.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__而不是打印出元组元素的所有内容(默认情况下会发生)。有 some questionssuper导致类似的错误,但它们:
  • 引用无参数版super()
  • 在 Python 3.6 中已经失败(它在 3.6 -> 3.8 升级之前对我有用)
  • 我不明白如何解决这个问题,因为它不是我可以控制的自定义元类,而是 stdlib 提供的 typing.NamedTuple .

  • 我的问题是如何在保持与 Python 3.6 的向后兼容性的同时解决此问题(否则我将只使用 @dataclasses.dataclass 而不是从 typing.NamedTuple 继承)?

    一个附带的问题是,考虑到有问题的 super,这怎么会在定义时失败。 call 在一个甚至还没有执行的方法中。例如:

    In [3]: class Test(typing.NamedTuple): 
    ...: a: int
    ...: b: float
    ...: def __repr__(self):
    ...: return foo

    有效(直到我们实际调用 __repr__ )即使 foo是 undefined reference 。是 super在这方面很神奇?

    最佳答案

    不幸的是,我不太熟悉 CPython 内部和类生成来说明它为什么会失败,但是有 this CPython bug tracker issue这似乎与 Python docs 中的一些词有关

    CPython implementation detail: In CPython 3.6 and later, the __class__ cell is passed to the metaclass as a __classcell__ entry in the class namespace. If present, this must be propagated up to the type.__new__ call in order for the class to be initialised correctly. Failing to do so will result in a RuntimeError in Python 3.8.



    所以可能在实际 namedtuple 期间的某个地方创建我们有一个电话到 type.__new__没有 __classcell__传播,但我不知道是不是这样。

    但是这种特殊情况似乎可以通过不使用 super() 来解决。调用时明确表示“我们需要 __repr__ 类的 object 方法”,例如

    class Test(typing.NamedTuple):
    a: int
    b: float
    __repr__ = object.__repr__

    关于python - `super` 子类中的 `typing.NamedTuple` 在 python 3.8 中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61543768/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com