python - set 和 frozenset 的继承行为似乎不同

标签 python inheritance immutability built-in-types

有人可以解释以下行为吗:

class derivedset1(frozenset):
    def __new__(cls,*args):
        return frozenset.__new__(cls,args)  

class derivedset2(set):
    def __new__(cls,*args):
        return set.__new__(cls,args)    

a=derivedset1('item1','item2') # WORKS 
b=derivedset2('item1','item2') # DOESN'T WORK

Traceback (most recent call last):
  File "inheriting-behaviours.py", line 12, in <module>
    b=derivedset2('item1','item2') # DOESN'T WORK
TypeError: derivedset2 expected at most 1 arguments, got 2

令我惊讶的是,您可以更改卡住集的构造函数,而可变集的构造函数则不可能。

最佳答案

来自Python documentation :

If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().

set.__init__ 只接受一个参数,一个指定初始集合内容的可迭代对象。因此,你应该添加你自己的初始化器,它接受所有额外的参数并将它们作为初始设置值提供:

class derivedset2(set):
    def __new__(cls,*args):
        return set.__new__(cls,*args)

    def __init__(self, *initial_values):
        set.__init__(self, initial_values)

请注意,您应该覆盖 __init__ 并避免实现 __new__ 除非您想要实现对象缓存、单例或类似奇怪的东西。您的子类化适用于 frozenset 正是因为 frozenset 确实 从对象缓存中获益,即 Python 解释器只需要一个 frozenset具有相同内容的两个 frozenset 对象的实例。

一般来说,你应该避免对内置类进行子类化,尤其是当你的语义不兼容时(在这种情况下,set([])derivedset2([]) 返回完全不同的结果)。

关于python - set 和 frozenset 的继承行为似乎不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4850370/

相关文章:

python - 在 docker 容器中安装 m2crypto

python - 为 Bitnami Django Stack 安装模块

python - 如何修复 python3、django2 中的 "unexpected token ' ]' "错误?

python - 用户定义的类是可变的

python - 在 pandas 数据框中重新采样 Hz

oop - [incr Tcl] 中的静态函数继承

Java:实例化还是继承?

java - 在没有构造函数的类上调用 super()

f# - 访问外部程序集中结构的公共(public)只读成员

ios - 导致 "Cannot pass immutable as inout"的 Swift 3 转换