Могу ли я создать подкласс перечисления, в котором я определил __новый__ метод?

#python #python-3.x #enums

#python #python-3.x #перечисления

Вопрос:

Я хочу создать псевдоабстрактный (без проблем с использованием ABC) класс Enum и разделить его на подклассы в разных классах. Все мои подклассы будут использовать один и тот же __new__ метод, поэтому я хотел бы определить его в суперклассе. При этом я столкнулся с AttributeError: 'NoneType' object has no attribute '_value_' , когда определял подкласс.

Моя попытка:

 from enum import Enum
class BasePattern(Enum):
    def __new__(cls, pattern, groups):
        obj = object.__new__(cls)
        obj._value_ = pattern
        obj.groups = groups
class ExamplePattern(BasePattern):
    example1 = (r"regex", ["group1"])
  

Есть ли простой способ заставить это работать, или было бы лучше определить общее __new__ в каждом подклассе? Если это вызывает беспокойство, я использую Python3.7.7.

Комментарии:

1. Могу я спросить, какую проблему вы пытаетесь решить? Это похоже на проблему XY и, похоже, создает больше проблем вместо решения исходной

2. __new__() должен возвращать что-то, что станет значением экземпляра. Вы создаете None s здесь.

3. @jasonharper: это была моя проблема, это было настолько очевидно, что я ее пропустил… Если вы хотите превратить свой комментарий в ответ, я приму его.

4. @DeepSpace Я рефакторингую некоторый код, используемый для анализа различных типов юридических текстов. Конечная цель — расширить его (добавить новые типы текстов в его область видимости). Каждый тип текста в настоящее время обрабатывается определенным перечислением, и все они похожи. Вот почему я пытаюсь использовать суперкласс.

Ответ №1:

Каждый раз, когда вы используете, __new__ вы должны возвращать объект — в противном случае None возвращается (что является значением по умолчанию для любой функции / метода в Python).

Что касается подкласса вашего собственного Enum базового класса — пока у вас нет членов в этом базовом классе, все будет в порядке — укажите столько поведения по умолчанию, сколько вам нужно.

Примечание: в вашем ExamplePattern классе вам не нужен внешний набор круглых скобок; круглые скобки — это оператор группировки, необходимый только для создания кортежей, когда есть двусмысленность — запятая, , — это то, что создает кортеж:

 >>> a = 1, 2
>>> type(a)
<class 'tuple'>

>>> b = (5 )  # no comma
>>> type(b)
<class 'int'>