set和Frozenset的继承行为似乎有所不同 [英] Inheriting behaviours for set and frozenset seem to differ

查看:132
本文介绍了set和Frozenset的继承行为似乎有所不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以解释以下行为:

Can someone explain the following behaviour:

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

这让我很惊讶,您可以更改冻结集的构造函数,而可变集的构造函数却不可能.

This is surprising to me that you can alter the constructor of a frozen set whereas it is not possible for the constructor of a mutable set.

推荐答案

来自 Python文档:

如果__new__()返回cls的实例,则将像__init__(self[, ...])一样调用新实例的__init__()方法,其中self是新实例,其余参数与以前相同.传递给__new__().

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__仅采用一个参数,该参数是可迭代的,用于指定初始设置的内容.因此,您应该添加自己的初始化程序,该初始化程序接受所有其他参数并将其提供为初始设置值:

set.__init__ only takes one argument, an iterable specifying the initial set contents. Therefore, you should add your own initializer which takes all additional arguments and supplies them as the initial set values:

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对象.

Notice that you should overwrite __init__ and refrain from implementing __new__ unless you want to implement object caching, singletons, or similar weird stuff. Your subclassing works for frozenset precisely because frozenset does profit from object caching, i.e. the Python interpreter only needs one frozenset instance for two frozenset objects with the same content.

通常,您应该避免对内置类进行子类化,尤其是在您的语义不兼容的情况下(在这种情况下,set([])derivedset2([])返回的结果完全不同).

In general, you should refrain from sub-classing built-in classes, especially if your semantics are incompatible (in this case, set([]) and derivedset2([]) return totally different results).

这篇关于set和Frozenset的继承行为似乎有所不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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