如何在查找过程中使用`__getattribute__`方法?

Tim*_*Tim 5 python python-3.x

Nutshell中的Python描述:

__getattribute__上述查找过程中涉及的方法如何?

  • __getattribute__方法是在查找过程中调用的吗?

  • 或者,是否通过调用启动查找过程__getattribute__,然后执行两个链接中的所有工作?

谢谢.

Ash*_*ary 2

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
Run Code Online (Sandbox Code Playgroud)

LOAD_ATTR然后打电话PyObject_GetAttr

PyObject_GetAttr现在在对象类型上查找 或tp_getattrotp_getattr已弃用)槽。

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);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在,如果一个对象有自己的 then 实现,则使用该实现,否则它会根据类型__getattribute__回退到 或object.__getattribute__。如果指向且它指向,则为type.__getattribute__tp_getattroobjectPyObject_GenericGetAttrtypetype_getattro

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