Я просто играл с концепцией классов данных Python и абстрактных классов, и то, что я пытаюсь достичь, - это в основном создать замороженный класс данных, но в то же время иметь один атрибут в качестве свойства. Ниже мой код для этого:
import abc
from dataclasses import dataclass, field
class AbsPersonModel(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def age(self):
...
@age.setter
@abc.abstractmethod
def age(self):
...
@abc.abstractmethod
def multiply_age(self, factor):
...
@dataclass(order=True, frozen=True)
class Person(AbsPersonModel):
sort_index: int = field(init=False, repr=False)
name: str
lastname: str
age: int
_age: int = field(init=False, repr=False)
def __post_init__(self):
self.sort_index = self.age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value < 0 or value > 100:
raise ValueError("Non sensical age cannot be set!")
self._age = value
def multiply_age(self, factor):
return self._age * factor
if __name__ == "__main__":
persons = [
Person(name="Jack", lastname="Ryan", age=35),
Person(name="Jason", lastname="Bourne", age=45),
Person(name="James", lastname="Bond", age=60)
]
sorted_persons = sorted(persons)
for person in sorted_persons:
print(f"{person.name} and {person.age}")
Когда я запускаю это, я получаю следующую ошибку:
Traceback (most recent call last):
File "abstract_prac.py", line 57, in <module>
Person(name="Jack", lastname="Ryan", age=35),
File "<string>", line 4, in __init__
File "abstract_prac.py", line 48, in age
self._age = value
File "<string>", line 3, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field '_age'
Как я могу получить лучшее из обоих миров (классы данных, а также использование свойства вместе с ним)?
Любая помощь приветствуется.
__init__
, то же самое относится и к__post_init__
(как в реализации CPython внутренне__init__
вызывает__post_init__
). - person Kent Shikama   schedule 08.12.2019