gpt4 book ai didi

python - 覆盖 __class__ 引发 TypeError

转载 作者:行者123 更新时间:2023-11-28 22:16:32 28 4
gpt4 key购买 nike

我试图通过从该类派生并覆盖/添加某些方法来扩展用 C 编写的模块类的功能*。

问题是他的模块创建了我试图在不同地方扩展的类的实例。因此,我需要创建一个转换方法,将模块提供的基类转换为我自己的具有附加功能的派生类。

这是我尝试过的:

class Derived(Base):
@classmethod
def cast(cls, obj: Base):
obj.__class__ = cls

此方法适用于我自己创建的类层次结构 - 但是它在我使用的模块中失败,抛出以下异常:

TypeError: __class__ assignment only supported for heap types or ModuleType subclasses

我很难找到有关此异常的官方信息。任何信息都有帮助,我什至会接受 hacky 解决方案,只要它们是干净的并且完全模仿我正在寻找的行为。

* 我要扩展的类是 Surfacepygame 内。

最佳答案

__class__ 属性一直受到可接受的限制,Python 类比 C 中定义的类型灵活得多。

例如,__slots__ section in the datamodel documentation状态:

__class__ assignment works only if both classes have the same __slots__.

并且同一个文档调用了 instance.__class__ attribute 只读:

The implementation adds a few special read-only attributes to several object types, where they are relevant.

所以 __class__ 实际上并不意味着可写,但它已经存在了很长时间并且是一个非常有用的属性。

现在,在您的情况下,不允许分配,因为目标实例的类型不会在堆上分配对象(进程内存区域会增长以容纳任意数量的对象,它是大多数 Python 对象都是分配的)。未在堆上分配的对象的管理方式不同(例如,不受引用计数的影响),如果您更改了它们的类型,它们将突然需要以不同方式进行管理。目前不支持。

它是 briefly supported在 Python 3.5 候选发布版本中,允许在 modules 上设置 __class__,但是一旦发现可以更改 interned 不可变值的类型,这就会适得其反:

class MyInt(int):
# lets make ints mutable!

(1).__class__ = MyInt

1 是一个 interned value ,所以现在 在 Python 程序中所有对整数 1 的使用 都已更改。这不是您想要的,尤其是当您像 Google App Engine 那样跨多个进程重复使用解释器内存时!参见 issue #24912低调。

但这就是异常中特别提到模块实例的原因,参见Customising module attribute access .

您必须找到其他途径来解决您的问题。例如,也许您的特定问题可以通过包装使用 __getattr__ 的实例来解决将属性代理到包装的实例。

关于python - 覆盖 __class__ 引发 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52140811/

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