Why there is not __break__ dunder method - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: General (https://python-forum.io/forum-1.html) +--- Forum: News and Discussions (https://python-forum.io/forum-31.html) +--- Thread: Why there is not __break__ dunder method (/thread-39966.html) |
Why there is not __break__ dunder method - Phidias618 - May-13-2023 Hello, Yesterday I ran into an issue, i try to iterate multiple time trough a custom class, the class is a chess Board and iterating trough it would give a tuple of (x, y, tile) for each step of the loop to iterate multiple time I store all the variable that I will need in the __next__ method into a list and add that list to another list, iter_list but to work the __next__ method of the class delete the last element of iter_list juste before raising StopIteration that mean that if someone use break while iterating this class, the last element of iter_list would not be deleted So that why I ask this question, I search online and i saw that a can use the context manager but that didn't look good for me and I think that it isn't an obvious way to do it I think that a __break__ method would be usefull to iterate multiple time into a custom class and still use break inside the loop: like this: for *var0 in custom_iterator: ----for *var1 in custom_iterator: --------# do something --------if some_condition: ------------break So I wonder why there is not __break__ method RE: Why there is not __break__ dunder method - Gribouillis - May-13-2023 (May-13-2023, 02:43 PM)Phidias618 Wrote: So I wonder why there is not __break__ methodI think ther is no __break__ method because nobody needs it, so can you give a concrete example of what you want to do, because it is difficult to understand with an abstract description?
RE: Why there is not __break__ dunder method - Phidias618 - May-13-2023 class SomeBoard: def __init__(self, width, height): self.width = width self.height = height self.grid = [[0 for _ in range(width)] for _ in range(height)] self._iter_data: list[list] = [] def __getitem__(self, co: tuple[int, int]): return self.grid[co[1]][co[0]] def __iter__(self): self._iter_data.append([-1, 0]) return self def __next__(self): last = _iter_data[-1] last[0] += 1 if last[0] == self.width: last[0] = 0 last[1] += 1 if last[1] == self.height: del self._iter_data[-1] raise StopIteration return last[0], last[1], self.grid[last[0], last[1]] board = SomeBoard(8, 8) # do something with it for x, y, tile in board: break print(board._iter_data)The probleme is that i can't break when I iterate trough CustomBoard, because that will leave date inside _iter_data with a __break__ dunder I could simply solve this by: def __break__(self): del self._iter_data[-1]And now the iterator will work properly But if _iter_data were only made of one list containing the x and y coordinate then I couldn't iterate trough a CustomBoard instance like this: board = CustomBoard(8, 8) for x1, y1, tile1 in board: for x2, y2, tile2 in board: # do something ...The problem now is that this program will result in an endless loop RE: Why there is not __break__ dunder method - Gribouillis - May-13-2023 I don't understand exactly what your code is doing but in complex cases, a good design is to create an iterator class separate from the class upon which you iterate. This iterator class will carry the data necessary to the iteration steps and also the specific code, so the structure could be class SomeBoard: def __init__(self, width, height): self.width = width self.height = height self.grid = [[0 for _ in range(width)] for _ in range(height)] def __getitem__(self, co: tuple[int, int]): return self.grid[co[1]][co[0]] def __iter__(self): return BoardIterator(self) class BoardIterator: def __init__(self, board): self.board = board self._iter_data = [[-1, 0]] def __iter__(self): return self def __next__(self): ... # custom iteration code here board = SomeBoard(8, 8) # do something with it for x, y, tile in board: break print(board._iter_data)Note that the SomeBoard class has no __next__ method here. A SomeBoard instance is iterable but it is not an iterator.
RE: Why there is not __break__ dunder method - Phidias618 - May-13-2023 Thanks you |