gpt4 book ai didi

python - 如何在不使用 super 的情况下设置 __new__ 返回值的类别?

转载 作者:太空宇宙 更新时间:2023-11-03 11:51:31 24 4
gpt4 key购买 nike

我要B成为某个类的子类 A ,我想覆盖 A.__new__ 1。通常,我的代码将具有以下基本结构:

class B(A):
def __new__(cls, ...):
ret = super(B, cls).__new__(cls, ...)

# modify ret as needed

return ret # type(ret) is cls

# ...

这样,type(B(...))确实是B . (注意:super(B, cls).__new__(cls, ...) 中的省略号不需要与 B.__new__ 的签名中的省略号代表的项目相同。)

但现在假设我想使用某些工厂方法/函数 返回的值A_Factory (返回 A 类型的对象)作为变量 ret 的起始值在构造函数中。如果我只是这样编码:

class B(A):
def __new__(cls, ...):
ret = A_Factory(...)

# modify ret as needed

return ret # type(ret) is A

...然后type(B(...))将是 A , 不是 B .

设置 ret 类的正确方法是什么?在 B.__new__ 的第二个版本中以上,type(B(...))B ,更一般地说,对于任何直接或间接子类 CB , type(C(...))C


1 我知道通常不需要覆盖父类的 __new__ ,但在这里我对需要的不常见情况感兴趣。

最佳答案

您可以设置 __class__实例的属性是传递给 __new__cls:

class A(object):
def __init__(self):
self.x = 2

def A_Factory():
return A()

class B(A):
def __new__(cls):
ret = A_Factory()

ret.__class__ = cls # Override the class.

return ret # type(ret) is cls

class C(B):
pass


if __name__ == "__main__":
b = B()
print(b.x)
print(type(b))
print(isinstance(b, B))
print(isinstance(b, A))
c = C()
print(type(C))

输出:

2
<class '__main__.B'>
True
True
<class '__main__.C'>

不过,这有一些限制。 commit that added the ability to assign to __class__列出它们:

Make __class__ assignment possible, when the object structures are the same. I hope the test for structural equivalence is stringent enough. It only allows the assignment if the old and new types:

  • have the same basic size
  • have the same item size
  • have the same dict offset
  • have the same weaklist offset
  • have the same GC flag bit
  • have a common base that is the same except for maybe the dict and weaklist (which may have been added separately at the same offsets
    in both types)

它们还需要具有相同的 __slots__,如果您在任一类上定义了它们。实际上,这通常只意味着这两个类都需要在 Python 中实现。尝试使用常规 Python 类和 inttuple 或用 C 实现的其他内容不太可能奏效。

关于python - 如何在不使用 super 的情况下设置 __new__ 返回值的类别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26282774/

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