使用str为init子类化元组

时间:2017-02-23 00:53:43

标签: python inheritance constructor tuples subclass

我试图创建一个tuple的子类,它在所有方面都表现得像普通的tuple,除了我用一个字符串初始化它,该字符串首先由构造函数自动拆分(我也希望它的__str__()再次加入,但这不是问题所在。)

我认为这是直截了当的,并尝试过这样:

class C(tuple):
  def __init__(self, text):
    super(C, self).__init__(text.split(':'))

  def __str__(self):
    return '[%s]' % ':'.join(self)

c = C('one:two:three')  # I expect this to be like ('one', 'two', 'three')

所以我尝试传递一个text(一个str),将其拆分并用结果调用我的超类构造函数。我希望得到tuple([ 'one', 'two', 'three' ])的结果,我。即一个单词元组:('one', 'two', 'three')

但我得到了一个字符元组,我。即对于输入'one:two:three',我得到('o', 'n', 'e', ':', 't', 'w', 'o', ':', 't', 'h', 'r', 'e', 'e'),这正是我拨打tuple('one:two:three')时得到的结果。

我调试了这种情况,发现我的代码被正确执行了(我的__init__()被调用,并使用正确的值调用另一个__init__()。我还尝试用具体的super替换tuple.__init__(self, text.split(':'))构造,但这并没有改变任何东西。我还尝试传递tuple而不是list创建的split(),也没有变化。实际上,调用超级__init__()似乎没有任何效果。解释器仍然使用我最初传递的字符串初始化元组。

我错过了什么吗?为什么这不按预期工作?如何创建一个C类,它是tuple的子类,我可以通过调用C('one:two:three')来初始化C来获取('one', 'two', 'three')的实例,这是一个类似{{1}的元组1}}?

1 个答案:

答案 0 :(得分:2)

由于元组是不可变的,因此使用__new__代替__init__

class C(tuple):
    def __new__(cls, text):
        return super(C, cls).__new__(cls, text.split(':'))

    def __str__(self):
        return '[%s]' % ':'.join(self)

c = C('one:two:three')
print(c)
print(list(c))