lai*_*e9m 2 python python-internals
所以我想了解dir()功能的细节。首先我查看了它的实现:
https://github.com/python/cpython/blob/e76daebc0c8afa3981a4c5a8b54537f756e805de/Objects/object.c#L1450-L1477
/* Helper for PyObject_Dir: object introspection. */
static PyObject *
_dir_object(PyObject *obj)
{
PyObject *result, *sorted;
PyObject *dirfunc = _PyObject_LookupSpecial(obj, &PyId___dir__);
assert(obj);
if (dirfunc == NULL) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError, "object does not provide __dir__");
return NULL;
}
/* use __dir__ */
result = _PyObject_CallNoArg(dirfunc);
Py_DECREF(dirfunc);
if (result == NULL)
return NULL;
/* return sorted(result) */
sorted = PySequence_List(result);
Py_DECREF(result);
if (sorted == NULL)
return NULL;
if (PyList_Sort(sorted)) {
Py_DECREF(sorted);
return NULL;
}
return sorted;
}
Run Code Online (Sandbox Code Playgroud)
并发现该_dir_object函数本身并没有做任何工作,而是调用了__dir__内省对象的方法。
>>> def test(): pass
>>> test.__dir__
<built-in method __dir__ of function object at 0x10ee57ae8>
Run Code Online (Sandbox Code Playgroud)
那么如何知道它的执行情况呢?
__dir__是一个特殊的方法,所以至少在Python 3中查找类型:
>>> type(test)\n<class \'function\'>\n>>> \'__dir__\' in dir(type(test))\nTrue\n>>> type(test).__dir__\n<method \'__dir__\' of \'object\' objects>\n>>> dir(test) == sorted(type(test).__dir__(test))\nTrue\nRun Code Online (Sandbox Code Playgroud)\n请参阅数据模型的特殊方法查找部分:
\n\n\n对于自定义类,只有在 object\xe2\x80\x99s 类型上定义特殊方法的隐式调用才能保证正确工作,而不是在 object\xe2\x80\x99s 实例字典中定义。
\n
这正是该_PyObject_LookupSpecial()函数的作用,请参阅源代码typeobject.c:
>>> type(test)\n<class \'function\'>\n>>> \'__dir__\' in dir(type(test))\nTrue\n>>> type(test).__dir__\n<method \'__dir__\' of \'object\' objects>\n>>> dir(test) == sorted(type(test).__dir__(test))\nTrue\nRun Code Online (Sandbox Code Playgroud)\n那里的调用Py_TYPE()是重要的部分,是在类型__dir__上查找的。
方法__dir__是在object类型上实现的,并由函数类型继承,因此实现在函数object_dir()中。
对于Python 2,dir()实现更加精细,而且实际上还委托给其他函数!对于函数对象,它委托给_generic_dir()function。该函数参考__dict__以下类型:
res = _PyType_LookupId(Py_TYPE(self), attrid);\nRun Code Online (Sandbox Code Playgroud)\n其中merge_class_dict()递归地将类层次结构属性合并到最终结果中。
| 归档时间: |
|
| 查看次数: |
2126 次 |
| 最近记录: |