为什么属性必须是 Python 中的 class 属性?
Why do properties have to be class attributes in Python?
最近我一直在学习 Python 中的托管属性,属性和描述符的一个共同主题是必须将它们分配为 class 属性。但是我无处可以找到解释为什么,尤其是为什么不能将它们指定为实例属性的原因。所以我的问题实际上有两个部分:
- 为什么属性/描述符实例必须是 class 属性?
- 为什么属性/描述符实例不能是实例属性?
这是因为 Python 尝试解析属性的方式:
- 首先它检查它是否定义在 class 级别
- 如果是,它会检查它是 属性 还是数据描述符
- 如果是,则遵循此"path"
- 如果不是,它会检查它是否是一个简单的 class 变量(如果有的话,直到它的父 classes)
- 如果是,它检查实例是否覆盖此 class 属性值,如果是,它 returns 覆盖值,如果否,它 returns class 属性值
- 如果没有,它会检查实例是否声明了这个属性
- 如果是,则returns实例属性值
- 如果否,则抛出 AttributeError
瞧 ;-)
编辑
我刚刚发现 this link 比我解释得更好。
另一个不错illustration.
why do properties/descriptor instances have to be class attributes?
他们不必,他们就是。这是一个设计决定,可能有比我想象的更多的理由来支持它(简化实现,将 类 与对象分开)。
why can properties/descriptor instances not be instance attributes?
它们可能是,您始终可以覆盖 __getattribute__
以调用在实例上访问的任何描述符,或者如果您愿意,可以完全禁止它们。
请记住,Python 不会阻止您这样做并不意味着这是个好主意。
最近我一直在学习 Python 中的托管属性,属性和描述符的一个共同主题是必须将它们分配为 class 属性。但是我无处可以找到解释为什么,尤其是为什么不能将它们指定为实例属性的原因。所以我的问题实际上有两个部分:
- 为什么属性/描述符实例必须是 class 属性?
- 为什么属性/描述符实例不能是实例属性?
这是因为 Python 尝试解析属性的方式:
- 首先它检查它是否定义在 class 级别
- 如果是,它会检查它是 属性 还是数据描述符
- 如果是,则遵循此"path"
- 如果不是,它会检查它是否是一个简单的 class 变量(如果有的话,直到它的父 classes)
- 如果是,它检查实例是否覆盖此 class 属性值,如果是,它 returns 覆盖值,如果否,它 returns class 属性值
- 如果没有,它会检查实例是否声明了这个属性
- 如果是,则returns实例属性值
- 如果否,则抛出 AttributeError
瞧 ;-)
编辑
我刚刚发现 this link 比我解释得更好。
另一个不错illustration.
why do properties/descriptor instances have to be class attributes?
他们不必,他们就是。这是一个设计决定,可能有比我想象的更多的理由来支持它(简化实现,将 类 与对象分开)。
why can properties/descriptor instances not be instance attributes?
它们可能是,您始终可以覆盖 __getattribute__
以调用在实例上访问的任何描述符,或者如果您愿意,可以完全禁止它们。
请记住,Python 不会阻止您这样做并不意味着这是个好主意。