Есть ли в Python способ объявить классоподобный интерфейс со списком атрибутов, отличных от namedtuple? Я хочу сделать миксин из списка имен атрибутов. Моя лучшая попытка на данный момент:
# module1.py (user facing)
CUSTOM_FIELDS = ['eye_color', 'shoe_size']
# module2.py (inside my framework)
from collections import namedtuple
from typing import Union
class BasePerson:
name: Any
age: Any
CustomMixin = namedtuple('CustomMixin', CUSTOM_FIELDS)
Person = Union[BasePerson, CustomMixin]
# module3.py (user facing)
def f(a: Person):
# my objective is for IDEs like PyCharm to recognize a.eye_color and a.name
a.eye_color
a.name
Это довольно близко, так как IDE распознают атрибуты. Но он также показывает все остальные атрибуты для NamedTuple и кортежа (например, _asdict
и т. д.).
Мне нужно, чтобы пользователи определяли атрибуты как список полей, а не с синтаксисом обычного класса. Во-первых, для согласованности с остальной частью моего фреймворка. Во-вторых, использование синтаксиса класса открыло бы банку червей, поскольку вы можете делать в классах все, что не разрешено моей структурой.
Я также пробовал:
class CustomMixin:
__slots__ = CUSTOM_FIELDS
Но PyCharm этого не распознает. Я также посмотрел на typing.Protocol
, но он также требует объявления класса.
dataclasses.make_dataclass()
может сделать это; см. дубликат для общего обзора того, что делает модульdataclasses
. - person Martijn Pieters   schedule 18.02.2021type(_, _, _)
, но для классов данных, верно? - person DeepSpace   schedule 18.02.2021type()
; входные данные проверяются, имена без подсказки типа получают подсказкуtyping.Any
, а декоратор@dataclass()
применяется к результату для создания таких методов, как__init__
и__repr__
, в зависимости от используемых аргументов. - person Martijn Pieters   schedule 18.02.2021type()
функция используетtypes.new_class()
, чтобы правильно обрабатывать пользовательские метаклассы. - person Martijn Pieters   schedule 18.02.2021attrs
, который поддерживает Python 2.7, 3.5 и выше. - person Martijn Pieters   schedule 18.02.2021