Python使用覆盖型描述符

本文最后更新于:9 个月前

1- 导入模块

import abc

2 - 主要的几个基础类

class AutoStorage:
    __counter = 0
    def __init__(self, ):
        cls = self.__class__
        prefix = cls.__name__
        index = cls.__counter
        self.storage_name = '_{}#{}'.format(prefix, index)
        cls.__counter += 1

    def __get__(self, instance, owner):
        if instance is None:
            return self
        else:
            return getattr(instance, self.storage_name)

    def __set__(self, instance, value):
        if value > 0:
            setattr(instance, self.storage_name, value)
        else:
            raise ValueError('value must be > 0')


class Validated(abc.ABC, AutoStorage):
    def __set__(self, instance, value):
        value = self.validate(instance, value)
        super().__set__(instance, value)
    @abc.abstractmethod
    def validate(self, instance, value):
        """return validated value or raise ValueError"""

class Quantity(Validated):
    """a number greater than zero"""
    def validate(self, instance, value):
        if value <= 0:
            raise ValueError('value must be > 0')
        return value

class NonBlank(Validated):
"""a string with at least one non-space character"""
def validate(self, instance, value):
    value = value.strip()
    if len(value) == 0:
        raise ValueError('value cannot be empty or blank')
    return value

AutoStorage自动管理储存属性的描述符类。Validated扩展AutoStorage类的抽象子类,覆盖set方法,调用必须由子类实现的validate方法。

3 - 主要实现的类

class LineItem:
    description = NonBlank()
    weight = Quantity()
    price = Quantity()

    def __init__(self, description, weight, price):
        self.description = description
        self.weight = weight
        self.price = price

    def subtotal(self):
        return self.weight * self.price

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!