当__new __()不返回类的实例时继承 [英] Inheritance when __new__() doesn't return instance of class

查看:142
本文介绍了当__new __()不返回类的实例时继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

__ 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 of cls, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆