Исходный код EJIO.utils.interface.read_only_class
## /utils/interface/read_only_class.py
from typing import Any
from .static_class import StaticClassMeta
__all__ = [
'ReadOnlyMeta',
]
[документация]
class ReadOnlyMeta(StaticClassMeta):
"""
Метакласс, реализующий свойства только для чтения на уровне самого класса
и полностью запрещающий создание экземпляров.
"""
__slots__ = ()
def __setattr__(cls, name: str, value: object) -> None:
"""
Запрещает перезапись или добавление свойств в структуру.
:param name: Имя атрибута.
:param value: Новое значение атрибута.
:raises AttributeError: При попытке установки атрибута.
"""
if name.startswith('_'):
super().__setattr__(name, value)
return
raise AttributeError(f"Cannot modify immutable property '{name}' in static structure")
def __delattr__(cls, name: str) -> None:
"""
Запрещает удаление свойств из структуры.
:param name: Имя атрибута.
:raises AttributeError: При попытке удаления атрибута.
"""
if name.startswith('_'):
super().__delattr__(name)
return
raise AttributeError(f"Cannot delete property '{name}' from static structure")
def __getattribute__(cls, name: str) -> Any:
"""
Перехватывает абсолютно любые обращения к атрибутам класса.
Если атрибут является вызываемой функцией (методом), выполняет её
и возвращает результат.
:param name: Имя атрибута.
:return: Значение атрибута, или результат выполнения функции, если атрибут это функция.
"""
attr = super().__getattribute__(name)
if name.startswith('__') and name.endswith('__'):
return attr
# Защищаем методы жизненного цикла Disposable.
if name in ('clear', 'destroy'):
return attr
if isinstance(attr, staticmethod):
return attr.__func__()
if callable(attr):
return attr()
return attr