Исходный код EJIO.utils.interface.mutable_static_class

## /utils/interface/mutable_static_class.py

from typing import Any, NoReturn, Callable
from .static_class import StaticClassMeta

__all__ = [
    'MutableStaticMeta',
    'static_property',
]

[документация] class static_property: """ Кастомный маркер-дескриптор для объявления вычисляемых свойств внутри изменяемых статических структур. """ __slots__ = ('_func',) def __init__(self, func: Callable[..., Any]) -> None: self._func = func self.__doc__ = func.__doc__ #type ignore def __get__(self, instance: Any, owner: Any) -> Any: # Если обращение идет от имени класса, передаем контекст класса в функцию return self._func(owner)
[документация] class MutableStaticMeta(StaticClassMeta): """ Метакласс для изменяемых статических структур конфигурации. Запрещает создание экземпляров, но разрешает чтение функций класса как вычисляемых свойств (property) без круглых скобок. """ __slots__ = () def __delattr__(cls, name: str) -> NoReturn: """ Запрещает удаление атрибутов из статическрй структуры. :param name: Имя удаляемого атрибута. """ raise AttributeError(f"Cannot delete configuration property '{name}' from static structure.") def __getattribute__(cls, name: str) -> Any: """ Перехватывает чтение любых атрибутов. Если атрибут является вызываемым методом класса, автоматически выполняет его и возвращает результат. :param name: Имя запрашиваемого атрибута. :return: Значение запрашиваемого атрибута, либо выполненную функцию, если атрибут - это функция. """ # 1. Защита от бесконечной рекурсии: пропускаем дандеры и служебные маркеры if name.startswith('__') and name.endswith('__'): return super().__getattribute__(name) # 2. Проверяем явные декларации через декораторы в словаре класса if name in cls.__dict__: raw_attr = cls.__dict__[name] if isinstance(raw_attr, static_property): return raw_attr.__get__(None, cls) # 3. Обрабатываем обычные методы на уровне статического класса return super().__getattribute__(name)