子类`frozenset`多`__init__`参数和`__new__`的奇怪行为(Subclass

2019-10-30 05:04发布

你纪念这个副本之前,我已经阅读了这个问题并且这个问题 ,他们不回答我的问题(甚至似乎更加迷惑我,更何况,他们都在Python 2是我想知道的Python 3)。 从这个问题 ,明白为什么下面的代码,

from typing import Hashable


class UnorderedPair(frozenset):
    def __init__(self, left: Hashable, right: Hashable):
        self.left = left
        self.right = right
        super().__init__((left, right))
        if len(self) != 2:
            raise TypeError("There must be 2 distinct elements. Possible duplicate in {{{}, {}}}.".format(left, right))

    def __str__(self):
        return "{{left: {}, right: {}}}".format(self.left, self.right)


if __name__ == '__main__':
    p = UnorderedPair(1, 2)
    print(p)

产生以下错误。

TypeError: UnorderedPair expected at most 1 arguments, got 2

这是因为我需要重写__new__()以及__init__() 然而,这是它为我变得混乱。 继回答上述问题 ,它看起来像我应该重写__new__()如下。

from typing import Hashable


class UnorderedPair(frozenset):
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)

    def __init__(self, left: Hashable, right: Hashable):
        self.left = left
        self.right = right
        super().__init__((left, right))
        if len(self) != 2:
            raise TypeError("There must be 2 distinct elements. Possible duplicate in {{{}, {}}}.".format(left, right))

    def __str__(self):
        return "{{left: {}, right: {}}}".format(self.left, self.right)


if __name__ == '__main__':
    p = UnorderedPair(1, 2)
    print(p)

但是,这给了我同样的错误。 因此,也许(因为它是和以前一样省略了一些代码)我应该如下覆盖它。

def __new__(cls, left: Hashable, right: Hashable):
    return super().__new__(cls, (left, right))

但是,这提供了以下非常神秘的错误。

    super().__init__((left, right))
TypeError: object.__init__() takes no parameters

它有什么用做object.__init__() 无论如何,或许那时我应该重写如下所示。

def __new__(cls, left: Hashable, right: Hashable):
    return super().__new__(cls)

但是,这仍然给出了同样的错误。

    super().__init__((left, right))
TypeError: object.__init__() takes no parameters

那么,如何正确做到这一点,并使其发挥作用? (我觉得我的意图是从类的非工作定义清楚。)

文章来源: Subclassing `frozenset` with multiple `__init__` parameters, and strange behaviour of `__new__`