@FrolVII

Можно ли в качестве значения для поля класса данных python использовать генератор?

Вопрос, собственно, поместился в заголовок: можно ли в качестве значения для поля класса данных python использовать генератор? Пример того, как я это вижу:
from dataclasses import dataclass, field
from typing import Iterator

def default_generator():
    pass

def generator_1(qty):
    
    for i in range(qty):
        
        yield Cell(value=f"Ячейка {i} строки r1")

def generator_2(qty):

    for i in range(qty):
        
        yield Cell(value=f"Ячейка {i} строки r2")
    

@dataclass
class Cell:
    value: str = "Пустая ячейка"
    cut_value: str = None

    def __post_init__(self):
        self.cut_value = self.value[0:30]


@dataclass
class Row:
    cells: Iterator = field(default_factory=default_generator)


Теперь, если сделать так:
r1 = Row()
r2 = Row()

r1.cells = generator_1(3)
r2.cells = generator_2(5)

for i in range(5):
    cell_val = next(r1.cells, None)

    print (cell_val)

for i in range(5):
    cell_val = next(r2.cells)

    print (cell_val)


Все, вроде, будет нормально:
>>> Cell(value='Ячейка 0 строки r1', cut_value='Ячейка 0 строки r1')
>>> Cell(value='Ячейка 1 строки r1', cut_value='Ячейка 1 строки r1')
>>> Cell(value='Ячейка 2 строки r1', cut_value='Ячейка 2 строки r1')
>>> None
>>> None
>>> Cell(value='Ячейка 0 строки r2', cut_value='Ячейка 0 строки r2')
>>> Cell(value='Ячейка 1 строки r2', cut_value='Ячейка 1 строки r2')
>>> Cell(value='Ячейка 2 строки r2', cut_value='Ячейка 2 строки r2')
>>> Cell(value='Ячейка 3 строки r2', cut_value='Ячейка 3 строки r2')
>>> Cell(value='Ячейка 4 строки r2', cut_value='Ячейка 4 строки r2')


Или, все же, после такого грядут какие-либо неочевидные (для меня сейчас) последствия?
  • Вопрос задан
  • 79 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
r1 = Row()
r1.cells = generator_1(3)

Ну во-первых, это выглядит скорее как обычная переменная, а не как поле класса. Будь это хотя бы вида
r1 = Row(table, 3) # 3я строка таблицы table, это имело бы смысл

Во-вторых, что за "восход солнца вручную"?
for i in range(5):  # нам нужно знать длину строки?
    cell_val = next(r1.cells, None)
    print (cell_val)

Почему не сделать
for cell_val in r1:
    print (cell_val)

если генераторы по определению заточены под итерацию по ним.

В-третьих, реализация cut_value откровенно неудачная - это должно быть property. Сейчас, если value изменится, cut_value уже не будет ему соответствовать. Придётся помнить, что нужно изменять и то, и то.

Ну и главное - генераторы одноразовые! Тебе придётся явно перезадавать их после использования, что убивает весь смысл.

В целом, я бы сказал, что ты не понимаешь главную идею того, зачем вообще наворачивают подпрограммы, классы и прочие абстракции: спрятать сложность реализации за простым интерфейсом. Классом должно быть проще пользоваться, чем переписать его с нуля. В приведённом коде это не так.

Вообще, если тебе интересно, как организовать массив - посмотри в сторону numpy. Там очень удобно сделана работа с массивами, и даже небольшого подмножества фич будет достаточно. В общем-то, возникает вопрос, а так ли нужны отдельные классы Row и Column.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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