Python 如何在不使用super的情况下设置_new__返回的值的类?
我希望Python 如何在不使用super的情况下设置_new__返回的值的类?,python,factory,Python,Factory,我希望B成为某个类a的子类,并且我希望覆盖a.。\uuuuu new\uuuu1。通常,我的代码具有以下基本结构: 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。(注意:su
B
成为某个类a
的子类,并且我希望覆盖a.。\uuuuu new\uuuu
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)中的省略号。
中的省略号不必表示与B中省略号表示的项目相同的项目。
的签名。)
但是现在假设我想使用某个工厂方法/函数A_factory
(返回类型为A
的对象)返回的值作为构造函数中变量ret
的起始值。如果我只是将其编码:
class B(A):
def __new__(cls, ...):
ret = A_Factory(...)
# modify ret as needed
return ret # type(ret) is A
…那么类型(B(…)
将是A
,而不是B
在上面的B的第二个版本中,设置ret
类的正确方法是什么?新的type(B(…)
是B
,更一般地说,对于B
的任何直接或间接子类C
,type(C(…)
是C
1我知道通常不需要重写父类的\uuuuu new\uuuu
,但这里我感兴趣的是需要重写的不常见情况。您可以将实例的属性设置为传递到\uu new\uuu
中的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'>
2
真的
真的
不过,这也有一些局限性。报告列出了它们:
当对象结构为
一样。我希望对结构等效性的测试足够严格。
仅当新旧类型满足以下条件时,才允许分配:
- 基本尺寸相同
- 具有相同的项目大小
- 具有相同的dict偏移量
- 有同样的弱点
- 具有相同的GC标志位
- 有一个相同的公共基,除了dict和weaklist(可能以相同的偏移量单独添加)
(两种类型)
如果您在任何一个类上都定义了相同的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu插槽,则它们还需要具有相同的。实际上,这通常只是意味着这两个类都需要用Python实现。尝试使用常规Python类和int
或tuple
或其他用C实现的东西来实现这一点是不可能的。您是否坚持使用\uuuu new\uuu
,还是愿意接受其他解决方案?