Skip to content

抽象基类

请参阅 https://docs.python.org/zh-cn/3/library/abc.html

构建描述符对象

描述符是类,当通过获取、设置或删除访问时,它们也可以改变其他对象。描述符并不意味着独立。相反,它们应该由所有者类持有。在构建具有值相互依赖的属性的面向对象的数据库或类时,描述符很有用。当以几种不同的测量单位表示属性或表示计算的属性(例如从类中的原点到表示网格上的点的距离)时,描述符特别有用。

要成为描述符,类必须至少具有__get____set__和中的一个__delete__实现。让我们来看看那些神奇的方法:

  • __get__(self, instance, owner)

    定义检索描述符值时的行为。instance是所有者对象的实例。owner是所有者类本身。

  • __set__(self, instance, value)

    定义描述符值更改时的行为。instance是所有者类的实例,并且value是将描述符设置为的值。

  • __delete__(self, instance)

    定义删除描述符值时的行为。instance是所有者对象的实例。

现在,一个有用的描述符应用示例:单位转换。将 英尺 进行转化。

python
class Meter(object):
    """米"""

    def __init__(self, value=0.0):
        self.value = float(value)

    def __get__(self, instance, owner):
        return self.value

    def __set__(self, instance, value):
        self.value = float(value)


class Foot(object):
    """英尺"""

    def __get__(self, instance, owner):
        return instance.meter * 3.2808

    def __set__(self, instance, value):
        instance.meter = float(value) / 3.2808


class Distance(object):
    """定义距离对象"""
    meter = Meter()
    foot = Foot()

案例:摄氏度华氏度互相转换

python

class Celsius:
    def __init__(self, value=26.0):  # 3
        self.value = float(value)  # 4 cel.value = float(value)

    def __get__(self, instance, owner):  # 13
        print(self.value, '调用Cel的get')
        return self.value

    def __set__(self, instance, value):  # 7 cel, temp, 30
        print('调用cel的set')  # 8
        self.value = float(value)  # 9 cel.value = float(30)


class Fahrenheit:
    def __get__(self, instance, owner):  # 11   fah, temp, Temperature
        print(instance.cel * 1.8 + 32)  # 12 temp.cel
        return instance.cel * 1.8 + 32  # 14

    def __set__(self, instance, value):
        instance.cel = (float(value) - 32) / 1.8


class Temperature:
    cel = Celsius()  # 2
    fah = Fahrenheit()  # 5


temp = Temperature()  # 1
temp.cel = 30  # 6 调用修饰的 set
temp.fah  # 10 获取 fah 的 get
temp.fah = 90
temp.cel