Python描述符两种实现哪个正确?应参考哪份官方文档?
描述符协议实现疑问解答
两种描述符实现都是完全正确的,核心差异仅在于参数命名——Python对函数参数的名称没有强制要求,只要参数的位置和语义对应描述符协议的定义即可:
参数名的对应关系
两份文档里的参数只是命名风格不同,实际作用完全一致:
__get__的第二个参数:无论是叫obj还是instance,都是指访问属性的实例对象(当通过类访问时该参数为None)__get__的第三个参数:type/objtype和owner都代表属性所属的类(或其子类)__set__的第二个参数:obj和instance都是要赋值的目标实例对象
参考文档选择
- Python数据模型参考文档:属于语言的权威规范文档,定义了描述符协议的官方标准,适合深入理解底层机制和细节
- Python How-to指南:是实操性教程,用更通俗的示例讲解用法,适合入门学习和快速上手
两种实现的代码对比
How-to指南风格实现
import logging logging.basicConfig(level=logging.INFO) class LoggedAgeAccess: def __get__(self, obj, objtype=None): value = obj._age logging.info('Accessing %r giving %r', 'age', value) return value def __set__(self, obj, value): logging.info('Updating %r to %r', 'age', value) obj._age = value class Person: age = LoggedAgeAccess() # Descriptor instance def __init__(self, name, age): self.name = name # Regular instance attribute self.age = age # Calls __set__() def birthday(self): self.age += 1 # Calls both __get__() and __set__()
数据模型参考风格实现
import logging logging.basicConfig(level=logging.INFO) class LoggedAgeAccess: def __get__(self, instance, owner=None): value = instance._age logging.info('Accessing %r giving %r', 'age', value) return value def __set__(self, instance, value): logging.info('Updating %r to %r', 'age', value) instance._age = value class Person: age = LoggedAgeAccess() # Descriptor instance def __init__(self, name, age): self.name = name # Regular instance attribute self.age = age # Calls __set__() def birthday(self): self.age += 1 # Calls both __get__() and __set__()
内容的提问来源于stack exchange,提问作者fsyscall
相关产品推荐
相关产品推荐

