【问题标题】:Python subclassing a class with custom __new__Python 使用自定义 __new__ 子类化一个类
【发布时间】:2015-01-30 13:00:54
【问题描述】:

有一个类(不是我创建的,来自第 3 方库)没有声明 __init__object__init__ 除外),这是它的 __new__

def __new__(cls, uid):
    self = super().__new__(cls, uid)
    self._info = get_info_from_uid(uid)
    return self

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

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

class MyClass(TheirClass):
    def __init__(self, uid, my_stuff=()):
        super().__init__(uid)
        self.my_stuff = my_stuff

显然,这从object.__init__() 引发了一个 TypeError 不带参数。 我应该如何使用__new__ 子类化此类? 我是否只是将__new__ 方法重写为?

【问题讨论】:

  • __new__ 方法,如发布的那样,除非该类继承自 object 本身以外的其他东西,否则它将不起作用; object.__new__ 在这种情况下不接受参数。我希望它读到self = super().__new__(cls)
  • 另外,他们肯定会在那里使用get_info_from_uid(uid)(不是self.uid)吗?
  • @MartijnPieters 是的,它确实也继承了其他几个类,但它们也没有声明 __init__。是的,对self.uid 感到抱歉,这是我在尝试创建自己的课程时的拼写错误,忘记了。

标签: python inheritance python-3.x subclassing


【解决方案1】:

由于原始项目坚持使用__new__ 并在子类can get very tricky indeed 中同时使用__init____new__,因此您还必须在子类中使用__new__

class MyClass(TheirClass):
    def __new__(cls, uid, my_stuff=()):
        self = super().__new__(cls, uid)
        self.my_stuff = my_stuff
        return self

也许原作者觉得该类型应该被视为不可变的。

如果你坚持,你仍然可以使用__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

【讨论】:

  • “或许原作者觉得该类型应该被视为不可变类型。”,您能在这方面给我一点启发吗? __new__ 与使对象不可变有什么关系?编辑:是的,谢谢,我将覆盖我的子类中的__new__! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
相关资源
最近更新 更多