python复习–类相关–什么是描述符

一、一句话总览(先建立整体感)

描述符通过 getsetdelete
分别接管属性的:读取、赋值、删除 三种操作。

只要某个描述符对象实现了其中之一,
当对应的操作发生时,Python 就会自动调用这些方法。

二、get:读取属性时会发生什么

2.1 场景说明

当我们写:

print(p.age)

Python 并不是直接去拿值,
而是先看看 age 是不是描述符。

如果是,就会自动调用 get

2.2 示例:读取时返回值

class Age:
    def __get__(self, instance, owner):
        return instance.__dict__.get("_age")


class Person:
    age = Age()

    def __init__(self, age):
        self.age = age


p = Person(18)
print(p.age)   # 18

这里执行 p.age 时,实际上走的是 Age.get

小结一句话
get 决定:
“别人读这个属性时,能读到什么值”

三、set:给属性赋值时会发生什么

3.1 场景说明

当我们写:

p.age = 20

如果 age 是描述符,
Python 就会自动调用 set

3.2 示例:赋值时做校验

class Age:
    def __get__(self, instance, owner):
        return instance.__dict__.get("_age")

    def __set__(self, instance, value):
        if value <= 0:
            raise ValueError("年龄必须是正整数")
        instance.__dict__["_age"] = value


class Person:
    age = Age()

    def __init__(self, age):
        self.age = age


p = Person(18)
print(p.age)   # 18

p.age = -1     # ValueError

p.age = -1 并没有直接赋值,而是被 set 拦住了

小结一句话
set 决定:
“这个属性能不能被修改,以及怎么修改”

四、delete:删除属性时会发生什么

4.1 场景说明

当我们写:

del p.age

如果 age 是描述符,
Python 就会自动调用 delete

4.2 示例:禁止删除属性

class Age:
    def __get__(self, instance, owner):
        return instance.__dict__.get("_age")

    def __set__(self, instance, value):
        instance.__dict__["_age"] = value

    def __delete__(self, instance):
        raise AttributeError("年龄属性不能被删除")


class Person:
    age = Age()

    def __init__(self, age):
        self.age = age


p = Person(18)
print(p.age)   # 18

del p.age      # AttributeError

小结一句话
delete 决定:
“这个属性能不能被删,以及删的时候做什么”

五、三者对应关系

我们写的代码 自动触发的方法
p.age get
p.age = 20 set
del p.age delete
我们只是在“用属性”,
Python 自动在背后帮我们调用这些方法。

六、和普通方法的本质区别

普通方法:

p.set_age(20)

描述符:

p.age = 20

描述符让“属性”本身带上了规则,
而不是靠人记得去调用某个方法。
Python复习–对象相关–dict__与__get

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐