Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中初始化元组子类的实例?_Python_Python 3.x - Fatal编程技术网

如何在Python中初始化元组子类的实例?

如何在Python中初始化元组子类的实例?,python,python-3.x,Python,Python 3.x,可能重复: 我想定义一个继承自tuple的类,并希望能够使用tuple不支持的语法对其进行实例化。举个简单的例子,假设我想定义一个类MyTuple,它继承自tuple,我可以通过传递两个值x和y来实例化它,以创建(我的)tuple(x,y)。我尝试了以下代码: class MyTuple(tuple): def __init__(self, x, y): print("debug message") super().__init__((x, y)) 但

可能重复:

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

class MyTuple(tuple):
    def __init__(self, x, y):
        print("debug message")
        super().__init__((x, y))
但是当我尝试时,例如,
MyTuple(2,3)
我得到了一个错误:
TypeError:tuple()最多接受一个参数(给定2个)
。似乎我的
\uuuu init\uuuu
函数甚至没有被调用(基于我得到的错误和我的“调试消息”没有被打印的事实)

那么正确的方法是什么呢

我正在使用Python 3.2

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

x = MyTuple(2,3)
print(x)
# (2, 3)
使用
super
的困难之一是您无法控制下一步将调用哪些同名类的方法。因此,所有类的方法都必须共享相同的调用签名——至少相同数量的项。由于您正在更改发送到
\uuuu new\uuu
的参数数量,因此不能使用
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

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

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

您可能想看一看。请查看以下详细答案:(1)为什么您需要使用
\uuuuuu new\uuuu
而不是
\uuuuuuuu init\uuuu
(2)您还需要遵循哪些其他步骤。您可以使用
*tuple
(或
*args
)而不是
x,y
,然后它将推广到任意大小。有趣。我花了一些时间来理解现场作业和lambdas。您为什么不使用正常的
def
结构,有什么特别的原因吗?另外,如何“将所有未知方法查找转发到
\u tuple
”?对于lambdas没有特别的原因,我只是喜欢这样“绑定”函数
count=lambda:…
对我说“count被指定为_tuple的计数”。你可以使用
def\uu getattr\uuuu(self,attr):return self.\u tuple.\uu getattribute\uuuu(attr)
@ch3ka你的前向未知方法查找可以很好地用于旧样式的类,而不是新样式的类。对于新样式的类,必须定义魔法方法,例如
\uuuu iter\uuuu
\uuuu包含
,否则将引发
AttributeError
。新样式类将这些神奇的方法作为类的属性,只在该类中搜索,而不调用
\uuu getattr\uuu()