栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Python:__getattribute__方法和描述符

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python:__getattribute__方法和描述符

实际上,在CPython中,默认

__getattribute__
实现不是 Python
方法,而是在C中实现。它可以直接访问对象插槽(代表Python对象的C结构中的条目),而无需费心通过讨厌的属性访问例程。

仅仅因为您的 Python 代码必须执行此操作,并不意味着C代码必须这样做。:-)

如果您确实实现了Python

__getattribute__
方法,则只需使用
object.__getattribute__(self,attrname)
或更好
super().__getattribute__(attrname)
地访问上的属性即可
self
。这样,您也不会遇到递归。

在CPython实现中,属性访问实际上是由C类型对象中的

tp_getattro
插槽处理的,而后退到
tp_getattr
slot。

为了详尽无遗并充分展示C代码的功能,当您在 实例 上使用属性访问时,这里是称为的完整函数集:

  • Python将属性访问转换为对

    PyObject_GetAttr()
    C函数的调用。该函数的实现查找您的类的
    tp_getattro
    tp_getattr
    插槽。

  • object
    类型已用函数填充
    tp_getattro
    插槽,该
    PyObject_GenericGetAttr
    函数将调用委托给
    _PyObject_GenericGetAttrWithDict
    (将
    *dict
    指针设置为
    NULL
    ,将
    suppress
    参数设置为
    0
    )。此功能是您的
    object.__getattribute__
    方法(在名称和插槽之间映射一个特殊的表)。

  • _PyObject_GenericGetAttrWithDict
    函数可以
    __dict__
    通过
    tp_dict
    slot访问实例对象,但是对于 描述符 (包括方法),则使用该
    _PyType_Lookup
    函数。

  • _PyType_Lookup
    处理缓存并委托
    find_name_in_mro
    缓存未命中;后者在类(和超类)上查找属性。该代码使用指向
    tp_dict
    MRO中每个类上的插槽的直接指针来引用类属性。

  • 如果找到描述符,

    _PyType_Lookup
    则将其返回
    _PyObject_GenericGetAttrWithDict
    并调用该
    tp_descr_get
    对象上的函数(
    __get__
    挂钩)。

当您访问 类本身
的属性而不是时

_PyObject_GenericGetAttrWithDict
,该
type->tp_getattro
插槽将由
type_getattro()
函数提供服务,该函数也考虑了元类。此版本
__get__
也会调用,但将实例参数设置为
None

该代码无需递归调用

__getattribute__
即可访问该
__dict__
属性,因为它可以直接直接进入C结构。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/645755.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号