【问题标题】:How is the `__getattribute__` method involved in the lookup procedures?`__getattribute__` 方法如何参与查找过程?
【发布时间】:2017-12-12 22:21:34
【问题描述】:

Python in a Nutshell 描述:

__getattribute__方法是如何参与上述查找过程的?

  • __getattribute__ 方法是否在查找过程中的某处调用?

  • 或者,查找过程是通过调用__getattribute__ 启动的,然后两个链接中的所有工作都由哪个来完成?

谢谢。

【问题讨论】:

  • 鉴于您一直在询问的所有这些属性查找问题,我想您最终会想了解这部分内容。
  • Relevant,尽管关注的细节与您正在查看的不同。

标签: python python-3.x


【解决方案1】:

TLDR: 属性查找从调用__getattribute__ 开始,它会完成链接中提到的所有工作。根据对象的类型调用object.__getattribute__type.__getattribute__


任何属性查找都会在内部产生LOAD_ATTR 字节码。

>>> import dis    
>>> dis.dis(lambda: foo.x)
  1           0 LOAD_GLOBAL              0 (foo)
              2 LOAD_ATTR                1 (x)
              4 RETURN_VALUE

LOAD_ATTR 然后调用PyObject_GetAttr

PyObject_GetAttr 现在在对象类型上查找tp_getattrotp_getattr(deprecated) 槽。

PyObject *

PyObject_GetAttr(PyObject *v, PyObject *name)
{
    PyTypeObject *tp = Py_TYPE(v);
    ...
    if (tp->tp_getattro != NULL)
        return (*tp->tp_getattro)(v, name);
    if (tp->tp_getattr != NULL) {
        const char *name_str = PyUnicode_AsUTF8(name);
        if (name_str == NULL)
            return NULL;
        return (*tp->tp_getattr)(v, (char *)name_str);
    }
    ...
}

现在,如果一个对象有自己的__getattribute__ 实现,那么它会被使用,否则它会根据类型回退到object.__getattribute__type.__getattribute__tp_getattro slotobject 的情况下指向PyObject_GenericGetAttr,对于type 它指向type_getattro

PyObject_GenericGetAttrtype_getattro 基本上完成了检查描述符、字典、插槽等的所有工作(基于类型)并尝试返回一个值。如果他们在所有事情之后都找不到它,则引发AttributeError,并且如果对象的类型定义为__getattr__,那么它将被调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2011-09-08
    • 2020-02-13
    • 2012-10-04
    • 1970-01-01
    • 2018-08-24
    相关资源
    最近更新 更多