Форум сайта python.su
0
Делаю лист-подобный класс, и от него требуется по getitem выдавать функционирующий объект, инициализированный положенным значением.
Реализацией в лоб был МАП инициализационной секвенции и последующее создание объектов по append. Но оказалось, что это сильно дорого, и может повесить выполнение на 10 мин при одном листе на 1М элементов.
Вторая попытка в виде отдельной обработки случаев доступа к элементам на местах, вроде была шустрой, но выросла в кашу кода. Сейчас переписываются заново. Думаю, не сяду ли опять в лужу, если буду создавать объекты в getitem по запросу и кешировать их?
Офлайн
13
Почти ничего не понял, но понимаю в чем проблема. Использую модуль queue, класс Queue. Он вполне себе подходит. 1М объектов для него - фигня, никаких MemoryError не будет, этот модуль не пальцем деланый. А получить 1 объект стоящий последний можно используюя метод .get(), положить .put(). Пример:
from queue import Queue queue = Queue() # Make 1m queue.put(smthing) object_ = queue.get()
# Life loop while alive: if (fun > boredom) and money: pass_day(fun, boredom, money) continue else: break
Офлайн
0
Ох, с планшета ахинея всякая пишется…
Попробую завтра хоть 3g нормальный поймать - точнее ситуацию опишу.
Очередь - не совсем то. Проблема в создании кучи объектов без прямой надобности.
Офлайн
0
Прошу прощения, только получилось завести интернет на ноут.
В общем, суть проблемы:
Есть лист-подобный класс, который на вход принимает секвенцию. Он может принимать как встроенный тип int, так и кастомный, назовем его Int, у которого есть property value.
При приеме элемента типа Int он вызывает его метод value и сохраняет в приватный list значение int.
А при вызове __getitem__ он должен отдавать уже новый объект Int со своими специфическими атрибутами (допустим,
my_IntList[0].name == f'{my_IntList.name}[0]'
class IntList: def __init__(self, name, seq): self._name = name self._seq_duck_type(seq) self.__seq = self._make_seq(seq) def _make_seq(self, seq): for idx, item in enumerate(seq): if isinstance(item, Int): item = item.value self.__seq.append(Int(name=f'{self._name}[{idx}]', value=item)) def __getitem__(self, idx): idx = self._idx_duck_type(idx) return self.__seq[idx]
for item in seq: self.__seq.append(item)
for item in seq: self.__seq.append(Int(item))
def func(val, idx=None): if idx is None: return process(val.name, val.value) if isinstance(val, IntList): return process(f'{val.name}[{idx}]', val[idx])

class IntList(KspVar): def __init__(self, name, ref_type=None, item_type=None, size=None, seq=None): super().__init__(name, ref_type=ref_type) if not isinstance(item_type, type): raise TypeError('item_type has to be subclass of KspVar') if not issubclass(item_type, KspVar): raise TypeError( 'item_type has to be subclass of KspVar') self._item_type = item_type self.__name = name if seq is not None: self._seq = self._init_seq(seq) else: self._seq = list() if size is not None: if self._seq: if len(self._seq) < size: raise AttributeError( 'size has to be greater or equal length of seq') self._size = size self._init_size = size else: self._size = 0 self._init_size = None self._cashed = [None] * self._size def _init_seq(self, seq): if not isinstance(seq, list): raise TypeError('seq has to be instance of list') for item in seq: if not isinstance(item, self.ref_type): raise TypeError( 'all items of seq have to be instances of' + f'{self.ref_type}') return seq @property def item_type(self): return self._item_type def extend(self, seq): if not isinstance(seq, list): raise TypeError('has to be list') for val in seq: self.append(val) def __getitem__(self, idx): idx = self._check_idx(idx) self._check_cashed_item(idx) return self._cashed[idx] def __setitem__(self, idx, val): idx = self._check_idx(idx) self._seq[idx] self._check_cashed_item(idx) self._cashed[idx] <<= val def _check_idx(self, idx): if not isinstance(KspIntVar, int): raise TypeError('has to be int or int KspIntVar') if isinstance(idx, KspIntVar): idx = idx.val return idx def _check_cashed_item(self, idx): if self._cashed[idx] is None: self._cashed[idx] = \ self._item_type(name=f'{self.__name}[{idx}]', value=self._seq[idx])
Офлайн