当__new __()不返回类的实例时继承 [英] Inheritance when __new__() doesn't return instance of class
问题描述
当 __ new __
返回类的实例时,一切正常,我们可以创建没有问题的子类:
When __new__
return instance of class, everything is ok, we can create subclass with no problems:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
return self
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
return self
def __init__(self, p3):
super().__init__(1, 2)
self.p3 = p3
a = A(1, 2)
print(a.p2) # output: 2
b = B(3)
print(b.p3) # output: 3
$ b b
但是,
But,
如果
__ new __()
的cls
,则不会调用新的
实例的__ init __()
方法。
If
__new__()
does not return an instance ofcls
, then the new instance’s__init__()
method will not be invoked.
看起来我们必须在 __ new __()内调用
在子类中调用 __ init __()
) super().__ new __
时会导致错误:
Looks like we have to call __init__()
inside __new__()
directly, but this leads to error, when we call super().__new__
in subclass:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
self.__init__(p1, p2) # we should call __init__ directly
return [self] # return not instance
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
return self
def __init__(self, p3):
self.p3 = p3
a = A(1, 2)
print(a[0].p2) # output: 2
b = B(3) # TypeError: __init__() takes 2 positional arguments but 3 were given
print(b[0].p3)
如何解决?如果 A .__ new __()
不返回类的实例,如何创建 A
p>
How to resolve it? How to create A
's subclass if A.__new__()
doesn't return an instance of class?
推荐答案
如果你打算手动调用它,不要命名方法 __ init __
并使用每个类名称或直接在类上手动调用 __ init __
方法未绑定。
If you are going to call it manually, either don't name the method __init__
and use per-class names instead, or manually call __init__
methods unbound, directly on the class.
每类名称相对容易,您可以在开始时使用双下划线来通过 name mangling :
Per-class names are relatively easy, you can use double-underscores at the start to produce class-specific names through name mangling:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
self.__init(p1, p2) # call custom __init directly
return [self] # return not instance
def __init(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
self[0].__init(p3) # custom init
return self
def __init(self, p3):
self.p3 = p3
或直接在课程上:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
A.__init__(self, p1, p2) # call custom __init__ unbound
return [self] # return not instance
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
B.__init__(self[0], p3) # call custom __init__ unbound
return self
def __init__(self, p3):
self.p3 = p3
如果您这样做,您也可以使用自定义初始化工具 c $ c> __ new __ 总共:
If you are going this way, you may as well do away with a custom initialiser and just do your initialisation in __new__
altogether:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
self.p1 = p1
self.p2 = p2
return [self] # return not instance
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
self[0].p3 = p3
return self
毕竟, 在创建时可以访问该实例,您也可以在那里初始化该实例。
After all, you already have access to the instance at creation time, you may as well initialise it there and then.
这篇关于当__new __()不返回类的实例时继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!