Python使用自定义__new__对类进行子类化

Mar*_*nen 2 python inheritance subclassing python-3.x

有一个类(不是我创建的,来自第三方库)没有__init__声明(除了object's __init__),这是它的__new__:

def __new__(cls, uid):
    self = super().__new__(cls, uid)
    self._info = get_info_from_uid(uid)
    return self
Run Code Online (Sandbox Code Playgroud)

我不明白他们为什么不在__init__这里使用,但他们没有.

现在我想继承它并给它一个额外的属性; 在我检查类的源代码(仅文档)之前,我认为它只是__init__像其他人一样使用,所以这就是我所做的:

class MyClass(TheirClass):
    def __init__(self, uid, my_stuff=()):
        super().__init__(uid)
        self.my_stuff = my_stuff
Run Code Online (Sandbox Code Playgroud)

显然,这引发了一个object.__init__()不参加参数的TypeError .我应该如何将这个类子类化__new__?我只是覆盖__new__方法吗?

Mar*_*ers 7

由于原始项目在子类中坚持__new__并使用它们__init__并且__new__一起使用可能会非常棘手,因此您还必须__new__在子类中使用:

class MyClass(TheirClass):
    def __new__(cls, uid, my_stuff=()):
        self = super().__new__(cls, uid)
        self.my_stuff = my_stuff
        return self
Run Code Online (Sandbox Code Playgroud)

也许原作者认为该类型应该被视为不可变的.

你仍然可以使用__init__,如果你坚持,但你必须指定一个__new__方法,反正以考虑额外的参数你__init__现在需要:

class MyClass(TheirClass):
    def __new__(cls, uid, *args):
        # ignore the extra arguments
        return super().__new__(cls, uid)

    def __init__(self, uid, my_stuff=()):
        self.my_stuff = my_stuff
Run Code Online (Sandbox Code Playgroud)

  • “也许原作者觉得类型应该被视为不可变的。”,你能不能给我一点启示?`__new__` 与使对象不可变有什么关系?编辑:是的,谢谢,我将在我的子类中覆盖`__new__`!:) (2认同)