Python:简明属性

Python: concise properties

我正在 Python 中实现一个 class,它有很多属性。这是 属性:

的示例
class Test:
    def __init__(self):
        self._value = None

    def get_value(self):
        if self._value is None:
            self._value = datetime.datetime.now()
        return self._value

    def set_value(self, new_value):
        self._value = new_value

    value = property(get_value, set_value)

代码好像很多。

有没有更简洁的方法来实现这个模式?如果有任何不同,我正在使用 PyCharm。

您可以使用 property 装饰器:

class Test:

    def __init__(self):
        self._value = None

    @property
    def value(self):
        if self._value is None:
            self._value = datetime.datetime.now()
        return self._value

当然,在这种情况下,您也可以通过以下方式获得几乎相同的行为:

    def __init__(self):
        self.value = datetime.datetime.now()

不同之处在于 @property 的解决方案默认为 read-only(请参阅有关添加 setter 和删除方法的文档),而后者的解决方案会创建一个 read/write属性。

如果您的某些属性具有相同的 logic/validation,您可以编写自己的描述符(属性是描述符)。

例如,我只接受长度大于 3 的字符串。我创建了一个描述符 ValidName,而不是两个属性,一个用于 first_name,一个用于 last_name first_namelast_name:

class ValidName:
    def __set_name__(self, owner, name):
        self.name = f"_{name}"

    def __set__(self, instance, value):
        if len(value) < 3:
            raise ValueError("The lenght must be larger than 3.")
        setattr(instance, self.name, value)

    def __get__(self, instance, owner):
        return getattr(instance, self.name)


class Person:
    first_name = ValidName()
    last_name = ValidName()

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name