Исходный код EJIO.utils.struct.stack
## /utils/struct/stack.py
from threading import Lock
__all__ = [
'Stack',
]
from typing import Any, Generator
class Node[T]:
"""
Узел связного списка для хранения значения и указателя на следующий элемент.
"""
__slots__ = ('value', 'next')
def __init__(self, value: T, next: 'Node[T] | None' = None) -> None:
"""
Создает узел связного списка.
:param value: Значение записываемое в узел.
:param next: Ссылка на следующий узел.
"""
self.value: T = value
self.next: 'Node'[T] | None = next
[документация]
class Stack[T]:
"""
Потокобезопасный стек на односвязном списке.
Класс поддерживает основные операции push, pop, peek, size, empty.
"""
__slots__ = ('_top', '_size', '_lock')
def __init__(self) -> None:
"""Создает объект очереди."""
self._top: Node[T] | None = None
self._lock: Lock = Lock()
self._size: int = 0
[документация]
def push(self, item: T) -> None:
"""
Добавляет элемент на вершину стека.
:param item: Объект для добавления.
"""
with self._lock:
self._top = Node(item, self._top)
self._size += 1
[документация]
def pop(self) -> T:
"""
Удаляет и возвращает верхний элемент стека.
:return: Объект из начала стека.
:raises IndexError: Если стек пуст.
"""
with self._lock:
if self._top is None:
raise IndexError("Pop from empty stack")
node = self._top
self._top = node.next
self._size -= 1
return node.value
[документация]
def peek(self) -> T:
"""
Возвращает верхний элемент стека без удаления.
:return: Объект из начала стека.
:raises IndexError: Если стек пуст.
"""
with self._lock:
if self._top is None:
raise IndexError("Peek from empty stack")
return self._top.value
@property
def empty(self) -> bool:
"""
Проверяет пуст ли стек.
:return: True если стек пуст, иначе False.
"""
with self._lock:
return self._top is None
@property
def size(self) -> int:
"""
Возвращает текущий размер стека.
:return: Размер стека.
"""
with self._lock:
return self._size
def __iter__(self) -> Generator[T, Any, None]:
"""
Возвращает итератор, который извлекает элементы из стека
до тех пор, пока стек не опустеет.
Потокобезопасно на уровне отдельных операций.
:yields: Элементы стека в порядке с начала до конца.
"""
while True:
try:
yield self.pop()
except IndexError:
return
def __str__(self) -> str:
"""
Возвращает строковое представление всего стека в виде списка элементов
от вершины к основанию.
:return: Представление стека в виде строки.
"""
with self._lock:
elements = []
current = self._top
while current:
elements.append(repr(current.value))
current = current.next
return f"[{', '.join(elements)}]"
def __repr__(self) -> str:
"""
Возвращает строковое представление всего стека в виде списка элементов
от вершины к основанию.
:return: Представление стека в виде строки.
"""
return f"Stack({str(self)})"
def __del__(self) -> None:
"""Очищает память при удалении объекта, чтобы избежать рекурсии."""
with self._lock:
current = self._top
while current:
next_node = current.next
current.next = None
current = next_node
self._top = None
self._size = 0