9

重複の可能性:
複数の__init__引数を持つPythonタプルのサブクラス化

から継承するクラスを定義したいのですがtuple、でサポートされていない構文を使用してインスタンス化できるようにしたいですtupleMyTuple簡単な例として、から継承し、2つの値とtupleを渡してインスタンス化できるクラスを定義して(my)タプルを作成するとします。私は次のコードを試しました:xy(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__関数は呼び出されていないようです(私が得たエラーと、私の「デバッグメッセージ」が出力されなかったという事実に基づいています)。

では、これを行う正しい方法は何ですか?

Python3.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)

使用上の難点の 1 つはsuper、同じ名前のどのクラスのメソッドが次に呼び出されるかを制御できないことです。したがって、すべてのクラスのメソッドは同じ呼び出しシグネチャ (少なくとも同じ数の項目) を共有する必要があります。に渡す引数の数を変更しているため__new__、 は使用できませんsuper


または、Lattyware が示唆するように、namedtuple を定義することもできます。

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 に答える