描述符是python中用于自定义属性访问行为的对象,其核心在于实现__get__、__set__和__delete__方法。1. __get__用于获取属性值,当访问属性时触发;2. __set__用于设置属性值,控制赋值过程;3. __delete__用于删除属性。描述符必须作为类属性存在才生效,且数据描述符(含__set__或__delete__)优先级高于实例字典。若将值存储在描述符自身,会导致所有实例共享该值,应避免此做法。掌握描述符机制有助于深入理解属性访问、装饰器及property等内置工具的实现原理,并可用于高级特性如类型检查和自动属性管理。
在Python中,描述符(Descriptor)是一种实现特定协议的对象,这个协议包含 __get__、__set__ 和 __delete__ 方法。通过这些方法,我们可以自定义类属性的访问行为。理解描述符的工作机制,有助于更深入掌握属性访问、装饰器、以及像 property 这样的内置工具背后的原理。
描述符的核心在于它定义了如何通过类或实例访问属性。一个对象只要实现了以下任意一个方法,就可以被称为描述符:
这些方法中的参数含义如下:
比如,当你访问 obj.attr 时,如果 attr 是一个描述符对象,那么实际上会调用它的 __get__ 方法。
立即学习“Python免费学习笔记(深入)”;
当访问某个属性时,Python解释器会在类和实例的命名空间中查找该属性。如果找到的是一个实现了 __get__ 的对象,并且这个对象是“数据描述符”(有 __set__ 或 __delete__)或者“非数据描述符”,那么就会触发 __get__ 方法。
举个例子:
class MyDescriptor: def __get__(self, instance, owner): print("Getting value") return 42 class MyClass: attr = MyDescriptor() obj = MyClass() print(obj.attr)
输出为:
Getting value 42
在这个例子中,访问 obj.attr 实际上调用了 MyDescriptor.__get__ 方法。这里的关键点是,描述符必须作为类属性存在于另一个类中才会生效,不能直接赋值给实例属性。
如果你希望描述符可以控制属性的赋值过程,就需要实现 __set__ 方法。这个方法会在你执行类似 obj.attr = value 的操作时被调用。
来看一个简单的实现:
class MyDescriptor: def __get__(self, instance, owner): print("Getting value") return self.value def __set__(self, instance, value): print("Setting value") self.value = value class MyClass: attr = MyDescriptor() obj = MyClass() obj.attr = 100 print(obj.attr)
输出:
Setting value Getting value 100
注意几点:
例如,在上面的例子中,如果我们想让每个 MyClass 实例都有自己的值,应该把值存在 instance 上:
def __set__(self, instance, value): instance._value = value def __get__(self, instance, owner): return instance._value
这样就能避免不同实例之间的值互相干扰。
使用描述符时有几个常见的坑需要注意:
基本上就这些内容了。描述符是Python底层机制的一部分,虽然不常用,但在实现高级特性如类型检查、自动属性管理等方面非常有用。掌握其原理,能让你写出更灵活、可控的类设计。
以上就是Python中描述符protocol 描述符协议__get__和__set__实现原理的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号