Tim*_*Tim 0 python attributes descriptor python-3.x python-internals
我知道__dict__ inobj.__dict__是 的描述符属性type(obj),因此查找obj.__dict__是type(obj).__dict__['__dict__'].__get__(obj)。
很容易说它
__dict__必须是一个描述符,因为__dict__将它实现为条目将需要您先找到 ,__dict__然后才能找到__dict__,但是在查找其他属性时,Python 已经绕过了正常的属性查找来查找__dict__,因此这并不像它最初听起来。如果描述符被替换为 each 中的一个'__dict__'键__dict__,__dict__仍然可以找到。
“Python 已经绕过正常的属性查找来查找__dict__”如何?“正常属性查找”是什么意思?
根据链接中引用的上下文,我不认为作者在撰写该内容时提到了查找obj.__dict__是type(obj).__dict__['__dict__'].__get__(obj).
正常的属性查找是通过调用__getattribute__hook或者更准确地说是C-API tp_getattroslot 来完成的。对此的默认实现在PyObject_GenericGetAttrC-API 函数中。
它的工作PyObject_GenericGetAttr,如果它们存在调用描述符,并看看实例__dict__。事实上,有是一个__dict__描述符,但它是更快__getattribute__的,只是访问__dict__的实例内存插槽结构直接,这就是实际执行的功能:
if (dict == NULL) {
/* Inline _PyObject_GetDictPtr */
dictoffset = tp->tp_dictoffset;
if (dictoffset != 0) {
if (dictoffset < 0) {
Py_ssize_t tsize;
size_t size;
tsize = ((PyVarObject *)obj)->ob_size;
if (tsize < 0)
tsize = -tsize;
size = _PyObject_VAR_SIZE(tp, tsize);
assert(size <= PY_SSIZE_T_MAX);
dictoffset += (Py_ssize_t)size;
assert(dictoffset > 0);
assert(dictoffset % SIZEOF_VOID_P == 0);
}
dictptr = (PyObject **) ((char *)obj + dictoffset);
dict = *dictptr;
}
}
Run Code Online (Sandbox Code Playgroud)
注意内联_PyObject_GetDictPtr注释;这是性能优化,因为实例属性查找很频繁。
如果您尝试instance.__dict__从 Python 代码访问,则调用描述符;它是一个数据描述符对象,因此在查看实例属性之前被调用。
| 归档时间: |
|
| 查看次数: |
316 次 |
| 最近记录: |