Python TypeHint描述符:GetSetDescriptorType使用与__get__签名问题
Python自定义描述符基类相关问题解答
1. 继承GetSetDescriptorType实现描述符基类的写法正确性
该写法完全错误,不可用。
types.GetSetDescriptorType是Python标准库提供的、用于标记C层面实现的同时具备__get__、__set__方法的内置描述符的类型标记(比如内置property就属于这类),它本身不允许被用户自定义类继承,运行时尝试继承会直接抛出TypeError: type 'getset_descriptor' is not an acceptable base type错误,仅适合用于isinstance类型判断场景。- 自定义描述符不需要继承任何特殊的系统基类:只要类中实现了
__get__/__set__/__delete__任意一个描述符协议方法,Python就会自动将其识别为描述符。如果需要抽取公共基类,直接继承默认的object写普通类即可。
2. PyCharm提示__get__签名不匹配的原因
该提示不是误报,你的代码存在两处明确问题:
- 第一,父类选择错误。
GetSetDescriptorType的类型存根中定义的__get__方法,第二个参数(所有者类参数)是带默认值的,你在子类中定义的objtype参数没有设置默认值,子类方法参数约束严于父类,违反里氏替换原则,类型检查器必然报签名不匹配。 - 第二,
__get__方法本身的签名不符合描述符协议规范:- 描述符被类直接访问(而非类实例访问)时,传入的
__obj参数值为None,你将其标注为MyObj类型本身就不符合实际运行逻辑; - 描述符协议规定
__get__的第二个参数(所有者类)必须设置默认值None,用于适配类直接访问描述符的场景。
- 描述符被类直接访问(而非类实例访问)时,传入的
符合规范的自定义描述符基类参考写法:
from typing import Any, Optional class MyDescriptorBase: def __get__(self, __obj: Optional[object], __owner: Optional[type] = None) -> Any: raise NotImplementedError # 数据描述符可按需实现__set__、__delete__方法
内容的提问来源于stack exchange,提问作者ProfHase85
相关产品推荐
相关产品推荐

