замороженный и переносимый класс данных с полем Iterable - PullRequest
0 голосов
/ 19 января 2019

Теперь, когда я окончательно отказался от поддержки Python 2, я перешел с attrs на Python 3 dataclasses, и есть одна проблема, с которой я особенно борюсь.

Допустим, у меня есть замороженный и хешируемый класс MyClass с одним полем my_field типа tuple.

Благодаря конвертерам attrs я смог предоставить гибкий API-интерфейс, позволяющий клиентам создавать экземпляры my_field с различными типами, такими как list, set или dict_keys. Все они будут автоматически преобразованы в tuple перед созданием класса.

Могу ли я сохранить этот API с dataclasses?

По запросу небольшой пример кода:

@attr.s(frozen=True, hash=True)
class MyClass:
    my_field = attr.ib(default=tuple(), converter=tuple)


print(MyClass([1, 2, 3]))

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Установка значения атрибута через базовый класс в шаге post_init, кажется, работает:

@dataclass(frozen=True)
class MyClass:
    my_field: Sequence[str]

    def __post_init__(self):
        super().__setattr__('my_field', tuple(getattr(self, 'my_field')))

Реализация миксина:

class ValidationError(AttributeError):
    pass


class ConversionValidationField(Field):

    def __init__(self, default=MISSING, default_factory=MISSING, init=True, repr=True,
                 hash=None, compare=True, metadata=None, converter=None, validator=None):
        self.converter = converter
        self.validator = validator
        super().__init__(default, default_factory, init, repr, hash, compare, metadata)


class ConversionValidationMixin:

    def __post_init__(self):
        for field in fields(self):
            if isinstance(field, ConversionValidationField):
                if field.converter:
                    super().__setattr__(field.name, field.converter(getattr(self, field.name)))

                if field.validator:
                    if not field.validator(getattr(self, field.name)):
                        raise ValidationError('Validation failed for {}.'.format(field.name))
0 голосов
/ 20 января 2019

Нет, конвертеры - это одна из вещей, которую PEP класса данных решил не реализовывать, чтобы сохранять их просто. http://www.attrs.org/en/stable/why.html#data-classes упоминает еще несколько.

DC являются строго подмножеством attrs, и маловероятно, что они когда-либо изменятся.

...