我想創建一個“回圈串列”物件:我可以通過它回圈地、永遠地迭代。為此,我嘗試這樣子list類化該類:
from itertools import cycle
class Circle(list):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __iter__(self):
sup_iter = super().__iter__()
return cycle(sup_iter)
list而且,確實,它作業得很好(在某種程度上。正如一些答案所指出的那樣,不可能將其轉換回 a )。但是,如果我嘗試將我的類基于deque該類,我似乎不能再呼叫我的str或repr我的物件,因為這樣做會使 python 解釋器凍結,并且該行程最終被終止。請記住,當類繼承自list.
我很茫然,任何人都可以幫助了解發生了什么嗎?
uj5u.com熱心網友回復:
CPython 中的串列 repr 在這里定義:https ://github.com/python/cpython/blob/v3.10.3/Objects/listobject.c#L361-L415
重要的一點是這個回圈使用
for (i = 0; i < Py_SIZE(v); i) { ...
而且您根本不會覆寫物件的大小,因此Circle([1,2,3])就串列 repr 而言, a 仍然具有 3 個元素。回圈對每個元素執行一次 repr,然后結束。
CPython 中的雙端佇列代表在這里定義:https ://github.com/python/cpython/blob/v3.10.3/Modules/_collectionsmodule.c#L1376-L1404
重要的一點是這段代碼使用
aslist = PySequence_List(deque);
即它首先將雙端隊串列示為一個串列,對于您的Circle班級來說,這將是一個無限回圈,最終會消耗所有可用記憶體并似乎凍結您的計算機。
uj5u.com熱心網友回復:
將它們轉換為串列和呼叫 repr (在構建 repr 字串的程序中將嘗試將其轉換為串列)都將嘗試遍歷雙端佇列。
但是你通過讓迭代永無止境“打破”了這一點。
有人可能會說執行此操作的代碼(最終,here)可以查看物件的長度(如果它有一個,則并非全部都會)并在那么多元素之后停止,但它不會:
/* Run iterator to exhaustion. */
for (;;) {
PyObject *item = iternext(it);
...
IMO,您最好保持__iter__原樣并使用cycle(your_circle)您想要迭代回圈串列的位置。
uj5u.com熱心網友回復:
當然,您不能呼叫list無限迭代器。on 迭代器的定義list是它繼續讀取元素,直到迭代器告訴它沒有更多元素為止。
你知道itertools.cycle嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/446636.html
