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