[英]How do I make a class that is also a list?
我想用Python创建一个具有各种属性和方法的类,但是为了继承列表的功能,我可以将对象附加到对象本身,而不是任何属性。 我希望能够说' graph[3]
',而不是' graph.node_list[3]
'。 有没有办法做到这一点?
你真正需要做的就是提供__getitem__
In [1]: class Foo:
...: def __init__(self, *args):
...: self.args = args
...: def __getitem__(self, i):
...: return self.args[i]
...:
In [2]: c = Foo(3,4,5)
In [3]: c[2]
Out[3]: 5
In [4]: c[3]
IndexError: tuple index out of range #traceback removed for brevity
In [5]: for i in c: print(i) #look, ma, I can even use a for-loop!
3
4
5
附录:您可能还想提供其他方法。 __len__
绝对是其中之一。 有一个相当长的魔术方法列表,我建议通过它们并选择有意义的方法。
你可以从list
继承:
class Foo(list):
def __init__(self):
pass
但是内置类型的子类化不一定是个好主意。
collections.abc.Sequence
(或者从3.5开始, typing.Sequence[T]
)是我这样做的方式。
您想添加一些特殊方法,例如列表中的__getitem__
。 看一眼:
https://docs.python.org/2/reference/datamodel.html#emulating-container-types
由于Python使用duck typing ,因此列表与任何其他对象之间的主要区别在于它公开的方法集。 您可以使用dir()
函数轻松查看对象的主要属性(方法和字段)。
>>> [a for a in dir([]) if callable(getattr([], a))]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__',
'__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__',
'__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
显然这里有很多方法,你可能并不关心它们中的大部分。 但如果你的目标是真正复制列表的行为,你可能想要实现它们。 如果你想查找它们,大多数__...__
方法都是在Python的数据模型中定义的。
从该页面:
可变序列应提供方法
append()
,count()
,index()
,extend()
,insert()
,pop()
,remove()
,reverse()
和sort()
,如Python标准列表对象。 最后,序列类型应该通过定义下面描述的方法__add__()
,__radd__()
__iadd__()
,__mul__()
__iadd__()
,__mul__()
__iadd__()
,__mul__()
__rmul__()
和__imul__()
来实现加法(意思是连接)和乘法(意思是重复); 他们不应该定义其他数字运算符。 建议映射和序列都实现__contains__()
方法以允许有效使用in运算符; 对于映射,应该搜索映射的键; 对于序列,它应该搜索值。 进一步建议映射和序列都实现__iter__()
方法,以允许有效迭代容器; 对于映射,__iter__()
应与keys()相同; 对于序列,它应该迭代值。
您特别询问的功能是索引查找,由__getitem__
提供。 我建议__iter__()
实现__contains__()
和__iter__()
(也许是__len__()
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.