gpt4 book ai didi

python - __getattribute__ 方法和描述符

转载 作者:太空宇宙 更新时间:2023-11-03 13:00:10 24 4
gpt4 key购买 nike

根据 python 描述符指南 https://docs.python.org/howto/descriptor.html

新样式类中的方法对象是使用描述符实现的,以避免在属性查找中对它们进行特殊封装。

我的理解是,有一个方法对象类型实现了 __get__ 并在使用实例调用时返回绑定(bind)方法对象,在没有实例且仅调用时返回未绑定(bind)方法对象类(class)。该文章还指出,此逻辑是在 object.__getattribute__ 方法中实现的。像这样:

def __getattribute__(self, key):
"Emulate type_getattro() in Objects/typeobject.c"
v = object.__getattribute__(self, key)
if hasattr(v, '__get__'):
return v.__get__(None, self)
return v

然而 object.__getattribute__ 本身就是一个方法!那么它如何绑定(bind)到一个对象(没有无限递归)?如果它在属性查找中是特殊大小写的,这不会破坏删除旧式特殊大小写的目的吗?

最佳答案

实际上,在 CPython 中,默认的 __getattribute__ 实现不是 Python 方法,而是在 C 中实现的。它可以访问对象槽(C 结构中的条目表示Python 对象)直接访问,而无需费心去执行讨厌的属性访问例程。

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

如果您确实实现了 Python __getattribute__ 方法,只需使用 object.__getattribute__(self, attrname),或者更好的是,super().__getattribute__( attrname) 来访问 self 上的属性。这样你也不会遇到递归。

在 CPython 实现中,属性访问实际上是由 C 类型对象中的 tp_getattro slot 处理的,回退到 tp_getattr slot

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

当您访问类本身的属性时,而不是 _PyObject_GenericGetAttrWithDicttype->tp_getattro 槽由 type_getattro() function 服务,它也考虑了元类。此版本也调用 __get__,但将实例参数设置为 None

此代码无处必须递归调用 __getattribute__ 来访问 __dict__ 属性,因为它可以直接进入 C 结构。

关于python - __getattribute__ 方法和描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24863787/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com