繁体   English   中英

如何创建一个也是列表的类?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM