@mkone112
Начинающий питонист.

Реализация вложенных атрибутов класса?

Периодически возникает желание использовать вложенные атрибуты класса. Обычно я использую внутренний класс:
class Context:
    _event_loop = None

    class states:  # noqa
        INITIAL = 0
        CONNECTING = 1
        CONNECTED = 2
        CLOSED = 3
    ...

class async_socket(Context):  # noqa
    def __init__(self, *args):
        ...
        self._state = self.states.INITIAL

Но мне это решение кажется довольно грязным. Есть ли более чистый вариант?
P.S.
  1. Я знаю про возможность использования Enum и SimpleNamespace, но ищу более элегантное решение
  2. Приведенный код это просто пример иллюстрирующий вложенность атрибутов, ничего более.
  3. Я знаю что класс в классе это не гуд, но если ._states нужен только для использования в тех классах где они объявлены - это приведет с созданию дополнительного класса для каждого такого класса - две тысячи классов это не лучше чем тысяча классов с инкапсулированной реализацией.
  4. Я знаю про PEP8 и PascalCase, но сохраняю консистентность именования(как кстати рекомендует сам pep), а еще потому что мне так захотелось
  • Вопрос задан
  • 217 просмотров
Пригласить эксперта
Ответы на вопрос 3
@bacon
да лучше поднять выше, назвать со смыслом, а класс от enum наследовать, вполне продак решение будет
Ответ написан
lxstvayne
@lxstvayne
Люблю Python
Написать пакет, в котором всё разбить на модули types.py, context.py, async_socket.py. В types.py вынеси State, унаследованный от Enum.enum, в context.py свой Context, а в async_socket.py выноси AsyncSocket. Соблюдай PEP, придерживайся правил в названии классов.
Ответ написан
class _ContextState(enum.Enum):
   ...

class AsyncSocket(Context):
    def __init__(self, *args):
        self._state = _ContextState.INITIAL

Если короче, то:
  1. вложенные классы - это плохо
  2. названия классов всегда в PascalCase
  3. как и методы, классы могут быть приватными, если их название начинается с символа подчеркивания
  4. если все объекты класса предназначены только для внутреннего использования, то этот класс можно сделать приватным


Хотя иногда все же можно использовать вложенные классы, но только если они приватные и нужны только в одном классе:
class Context:
    class _State(enum.Enum):
        ...

    def __init__(self):
        self._state = Context._State.INITIAL
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы