Nutshell中的Python描述:
从类中获取属性时的查找过程,例如cls.name(参见第一部分为什么从类和实例获取属性的查找过程不同?)
__getattribute__上述查找过程中涉及的方法如何?
该__getattribute__方法是在查找过程中调用的吗?
或者,是否通过调用启动查找过程__getattribute__,然后执行两个链接中的所有工作?
谢谢.
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_getattro(tp_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__,那么它将被调用。