不能 return 来自 Class.__new__() 的子类实例

Cannot return Subclass instance from Class.__new__()

这是 Python 3 代码:

class Class:
  def __new__(cls, value):
    print(__class__, cls, value)
    return Subclass(value+1, value+2)

class Subclass(Class):
  def __new__(cls, value, value2):
    print(__class__, cls, value, value2)
    return object.__new__(Subclass)
  def __init__(self, *args):
    print(args)
    self.value = args


acctual_instance = Class(1)
print('acctual_instance:', acctual_instance.value, type(acctual_instance))

输出:

<class '__main__.Class'> <class '__main__.Class'> 1
<class '__main__.Subclass'> <class '__main__.Subclass'> 2 3
(2, 3)
(1,)
acctual_instance: (1,) <class '__main__.Subclass'>

即使我们从 Class.__new__(1) 中 return 编辑了 Subclass(2,3) 实例,acctual_instance.valueClass 的参数 1,而不是 (2,3)。这是预期的行为吗?为什么 Subclass.__init__() 是第二次调用?我如何 return Subclass(2,3) 来自 Class.__new__(1) 的实例?

更新: 如果从 class Subclass(Class) 中删除 Class 那么输出是:

<class '__main__.Class'> <class '__main__.Class'> 1
<class '__main__.Subclass'> <class '__main__.Subclass'> 2 3
(2, 3)
acctual_instance: (2, 3) <class '__main__.Subclass'>

关于 __new__() 的文档是 quite explicit 的:

Typical implementations create a new instance of the class by invoking the superclass's __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.

这是因为 class 初始化 Class(1) 或多或少等于

 obj = Class.__new__(Class, 1)
 obj.__init__(1)

在您的代码中,您在 __new__()

中创建了一个完全初始化的实例
return Subclass(value+1, value+2)

这将调用 obj2 = Subclass.__new__(cls, value + 1, value + 2),然后是 obj2.__init__(value + 1, value + 2),然后是 return obj2

这之后是对 obj.__init__(1) 的调用,在从 __new__() 调用 return 之后,如上文所述:第二个 __init__() 使用原始参数调用(1).因此 value == 1。第一次构造函数调用设置的初始值被第二次构造函数调用覆盖。

您的代码的改进版本可能是

class Class:
    def __new__(cls, value):
        return Subclass.__new__(cls, value + 1, value + 2)

class SubClass(Class):
    def __new__(cls, value1, value2):
        return object.__new__(Subclass)

    def __init__(self, *args):
        print(args)

instance = Base(1)
print(type(instance))

但是请注意,该版本对传递给 Subclass.__new__()value1value2 没有任何作用。

另请注意,在 Subclass.__init__() 中,您还应该调用 super().__init__()