【问题标题】:Python, subclassing immutable typesPython,子类化不可变类型
【发布时间】:2011-03-08 10:14:34
【问题描述】:

我有以下课程:

class MySet(set):

    def __init__(self, arg=None):
        if isinstance(arg, basestring):
            arg = arg.split()
        set.__init__(self, arg)

这按预期工作(使用字符串的单词而不是字母初始化集合)。但是,当我想对 set 的不可变版本做同样的事情时,__init__ 方法似乎被忽略了:

class MySet(frozenset):

    def __init__(self, arg=None):
        if isinstance(arg, basestring):
            arg = arg.split()
        frozenset.__init__(self, arg)

我可以用__new__ 实现类似的效果吗?

【问题讨论】:

  • 我认为__new__(..) 在雕刻不可变类型的实例时采取主动的原因是利用不可变性并保留返回现有实例(如果可用)的机会。 (但如果一个人不想要这种优势,那么他们可以在不与__new__(..) 混淆的情况下创建一个不可变类型。特别是,__new__(..) 不提供任何特殊上下文。仍然需要通过@987654328 修改不可变字段@ 或类似名称,无论是在 __new__(..) 还是 __init_(..) 内。)

标签: python set immutability


【解决方案1】:

是的,你需要重写__new__ 特殊方法:

class MySet(frozenset):

    def __new__(cls, *args):
        if args and isinstance (args[0], basestring):
            args = (args[0].split (),) + args[1:]
        return super (MySet, cls).__new__(cls, *args)

print MySet ('foo bar baz')

输出是:

MySet(['baz', 'foo', 'bar'])

【讨论】:

  • 超级! init 可以被弃用吗?
  • @EoghanM:不,__new__ 不同。基本上,__new__ 创建 查找实例,而__init__ 设置已创建的实例。覆盖__new__ 的主要原因是避免创建新的实例(例如,使SomeType () 始终返回相同的单例对象),或者子类化某些不可变类型,例如frozenset。详情请见docs.python.org/reference/datamodel.html#special-method-names
  • thx - 我的子问题在这里更清楚地提出:stackoverflow.com/questions/3131488
  • 另见 Python 文档中的 the FAQ
猜你喜欢
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
  • 2011-12-24
相关资源
最近更新 更多