170 похожих чатов

Привет, как принято делать класс iterable если у класса определены

методы __getitem__ и __len__?

типа так:
class FooIterator:
def __init__(self, foo):
self.foo = foo
self.idx = 0

def __next__(self):
if self.idx > len(self.foo):
raise StopIteration
result = foo[self.idx]
self.idx += 1
return result


class Foo:
def __iter__(self):
return FooIterator(self)

def __getitem__(self, i):
return i

def __len__(self):
return 5

FooIterator выглядит как стандартный паттерн. Нужно всегда его руками создавать для каждого класса или можно проще?

20 ответов

20 просмотров

Все зависит от самого класса

Станислав-Трухан Автор вопроса
Pavel Павлик
Все зависит от самого класса

Что значит зависит? Сделать класс итерируемым нужно для foreach loop. Если без iter, то StopIteration прямо в getitem кидать?

Если у класса нет iter, но есть getitem, то при итерации будут возвращаться значения от getitem. В начале 0 передаться, и т.д., пока getitem вроде бы LookupError не выкенет

Станислав-Трухан Автор вопроса
Pavel Павлик
Если у класса нет iter, но есть getitem, то при ит...

foreach ждет StopIteration. Кидать StopIteration в getitem выглядит так себе

Станислав Трухан
foreach ждет StopIteration. Кидать StopIteration в...

Не надо кидать StopIteration, я тебе про LookupError говорю

Я перепутал, там должен быть именно IndexError

Станислав-Трухан Автор вопроса
Pavel Павлик
Я перепутал, там должен быть именно IndexError

Работает, спасибо. А подскажите где найти в доке питона, что foreach обрабатывает еще и IndexError? https://docs.python.org/3/reference/compound_stmts.html#for тут что-то очень скудно описано. и здесь https://docs.python.org/3/glossary.html#term-iterable описано что чтобы любой класс стал iterable он может реализовать __iter__ метод или __getitem__, что реализует Sequence семантику (__getitem__() + __len__()). то есть в foreach я бы ожидал если класс реализует getitem + len, то проверка на выход за boundary будет сделана не мной, а внутри foreach, почему это не так?

Станислав Трухан
Работает, спасибо. А подскажите где найти в доке п...

Это так потому что тебе всё равно проверять выход за границы

Станислав Трухан
Работает, спасибо. А подскажите где найти в доке п...

Зачем тебе вообще это нужно всё? Обычно, очень редко необходимо свои коллекции реализовывать

Станислав-Трухан Автор вопроса
Pavel Павлик
Зачем тебе вообще это нужно всё? Обычно, очень ре...

Очень просто, есть класс Dataset и я хочу в foreach стиле по нему пробежаться

Станислав-Трухан Автор вопроса
Pavel Павлик
https://docs.python.org/3/library/functions.html#i...

Что-то ничего не вижу про IndexError :(

Станислав Трухан
Что-то ничего не вижу про IndexError :(

> or it must support the sequence protocol (the getitem() method with integer arguments starting at 0

Станислав-Трухан Автор вопроса
Pavel Павлик
Покажи этот класс

концептуально что-то такое: class Foo: def __init__(self, foos, bars, bazs): self.foos = foos self.bars = bars self.bazs = bazs size = len(foos) assert size == len(bars) assert size == len(bazs) self.size = size def __getitem__(self, i): if i < 0 or i >= len(self): raise IndexError result = dict( foo=self.foos[i], bar=self.bars[i], baz=self.bazs[i], ) return result def __len__(self): return self.size @staticmethod def load_from_file(filename): with open(filename, "rb") as handle: return pickle.load(handle) def write_to_file(self, filename): with open(filename, "wb") as handle: pickle.dump(self, handle)

Станислав-Трухан Автор вопроса
Pavel Павлик
> or it must support the sequence protocol (the ge...

это я тоже читал и все это интуитивно понятно, но явное описание того, что foreach словит indexerror exception не нашел где написано в доке, а куда стоит посмотреть, если про это забыл, в сорсы или просозалы pep?

Станислав Трухан
концептуально что-то такое: class Foo: def __i...

1) Нельзя использовать пикл для долговременного хранения данных (https://t.me/ru_python/1728527) он только для IPC 2) Почему бы сразу не хранить список словарей? Зачем отдельные списки?

Станислав Трухан
это я тоже читал и все это интуитивно понятно, но ...

Фрагмент, который я показал ссылается на sequence protocol, вот тут разъяснение, что это такое https://docs.python.org/3/reference/datamodel.html#object.__getitem__

Станислав-Трухан Автор вопроса
Pavel Павлик
1) Нельзя использовать пикл для долговременного хр...

1) у меня скорее рисерч проект, поэтому для простоты можно 2) в целом наверное можно хранить и список словарей, но getitem может вернуть чуть больше чем исходный словарь, то есть запроцессить что-нибудь налету и добавить какой-нибудь новый item. ну и когда приходит список словарей, сразу сказать что пришли валидные данные накладно, или проверять уже только в getitem или есть какой-то другой способ кроме как в конструкторе пробежаться по списку и провалидировать каждый элемент/словарь списка.

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта