簡體   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