如何在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()