9

可能重复:
使用多个 __init__ 参数子类化 Python 元组

我想定义一个继承自 的类tuple,并且我希望能够使用不支持的语法来实例化它tuple。举个简单的例子,假设我想定义一个MyTuple继承自的类tuple,我可以通过传递两个值x和来实例化它y,以创建(我的)元组(x, y)。我试过以下代码:

class MyTuple(tuple):
    def __init__(self, x, y):
        print("debug message")
        super().__init__((x, y))

但是,例如,当我尝试时,MyTuple(2, 3)我得到了一个错误:TypeError: tuple() takes at most 1 argument (2 given). 似乎我的__init__函数甚至没有被调用(基于我得到的错误和我的“调试消息”没有打印的事实)。

那么这样做的正确方法是什么?

我正在使用 Python 3.2。

4

2 回答 2

12
class MyTuple(tuple):
    def __new__(cls, x, y):
        return tuple.__new__(cls, (x, y))

x = MyTuple(2,3)
print(x)
# (2, 3)

使用的困难之一super是您无法控制接下来将调用哪些类的同名方法。所以所有类的方法必须共享相同的调用签名——至少相同数量的项目。由于您正在更改发送到的参数数量__new__,因此您不能使用super.


或者正如 Lattyware 所建议的,你可以定义一个命名元组,

import collections
MyTuple = collections.namedtuple('MyTuple', 'x y')

p = MyTuple(2,3)
print(p)
# MyTuple(x=2, y=3)
print(p.x)
# 2
于 2012-09-29T12:40:38.143 回答
1

另一种方法是封装一个元组而不是从它继承:

>>> class MyTuple(object):
    count = lambda self, *args: self._tuple.count(*args)
    index = lambda self, *args: self._tuple.index(*args)
    __repr__ = lambda self: self._tuple.__repr__()
    # wrap other methods you need, or define them yourself,
    # or simply forward all unknown method lookups to _tuple
    def __init__(self, x, y):
        self._tuple = x,y


>>> x = MyTuple(2,3)
>>> x
(2, 3)
>>> x.index(3)
1

这有多实用,取决于您需要多少功能和修改,以及您是否需要isinstance(MyTuple(2, 3), tuple).

于 2012-09-29T13:14:04.717 回答