gpt4 book ai didi

python - 在 Python 中使用卡住数据类时如何使用属性 setter

转载 作者:行者123 更新时间:2023-12-05 03:56:35 24 4
gpt4 key购买 nike

我只是在玩弄 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, value):
...

@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'

我怎样才能两全其美(数据类和同时使用属性)?

如有任何帮助,我们将不胜感激。

最佳答案

您可以执行 frozen 初始化器 in dataclasses itself does 的操作并使用 object.__setattr__ 来赋值。给定您的抽象类,此数据类定义应该有效:

@dataclass(order=True, frozen=True)
class Person:
sort_index: int = field(init=False, repr=False)
name: str
lastname: str
age: int
_age: int = field(init=False, repr=False) # can actually be omitted

def __post_init__(self):
object.__setattr__(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!")
object.__setattr__(self, '_age', value)

def multiply_age(self, factor):
return self._age * factor

运行你的测试套件现在应该返回预期的结果

Jack and 35
Jason and 45
James and 60

这是有效的,因为将数据类设置为 frozen 会禁用该类自己的 __setattr__ 并使其仅引发您看到的异常。它的父类(super class)(始终包含 object)的任何 __setattr__ 仍然有效。

关于python - 在 Python 中使用卡住数据类时如何使用属性 setter ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59221782/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com