根据源码分析,发现内建方法都是通过以下方式定义:
Python/bltinmodule.c
中的static PyMethodDef builtin_methods[]
Python/clinic/bltinmodule.c.h
中的BUILTIN_XYZ_METHODDEF
之类宏。Python/bltinmodule.c
或Python/clinic/bltinmodule.c.h
中的builtin_xyz
之类函数。
我这里要记录的 isinstance
也是这样,最终找到 builtin_isinstance
定义如下:
builtin_isinstance
Python/clinic/bltinmodule.c.h
#define BUILTIN_ISINSTANCE_METHODDEF \
{"isinstance", (PyCFunction)(void(*)(void))builtin_isinstance, METH_FASTCALL, builtin_isinstance__doc__},
static PyObject *
builtin_isinstance(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *obj;
PyObject *class_or_tuple;
if (!_PyArg_CheckPositional("isinstance", nargs, 2, 2)) {
goto exit;
}
obj = args[0];
class_or_tuple = args[1];
return_value = builtin_isinstance_impl(module, obj, class_or_tuple);
exit:
return return_value;
}
builtin_isinstance_impl
Python/bltinmodule.c
static PyObject *
builtin_isinstance_impl(PyObject *module, PyObject *obj,
PyObject *class_or_tuple)
/*[clinic end generated code: output=6faf01472c13b003 input=ffa743db1daf7549]*/
{
int retval;
retval = PyObject_IsInstance(obj, class_or_tuple);
if (retval < 0)
return NULL;
return PyBool_FromLong(retval);
}
PyObject_IsInstance
object.h
中的几个基本方法
// 直接的类型比对
static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
return ob->ob_type == type;
}
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
static inline int
PyType_HasFeature(PyTypeObject *type, unsigned long feature)
{
unsigned long flags;
flags = type->tp_flags;
return ((flags & feature) != 0);
}
#define PyType_FastSubclass(type, flag) PyType_HasFeature(type, flag)
static inline int _PyType_Check(PyObject *op) {
return PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS);
}
#define PyType_Check(op) _PyType_Check(_PyObject_CAST(op))
static inline int _PyType_CheckExact(PyObject *op) {
return Py_IS_TYPE(op, &PyType_Type);
}
#define PyType_CheckExact(op) _PyType_CheckExact(_PyObject_CAST(op))
PyObject_IsInstance
Objects/abstract.c
int
PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
PyThreadState *tstate = _PyThreadState_GET();
return object_recursive_isinstance(tstate, inst, cls);
}
static int
object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls)
{
_Py_IDENTIFIER(__instancecheck__);
/* 直接比对类型 */
/* Quick test for an exact match */
if (Py_IS_TYPE(inst, (PyTypeObject *)cls)) {
return 1;
}
/* We know what type's __instancecheck__ does. */
if (PyType_CheckExact(cls)) {
return object_isinstance(inst, cls);
}
/* 多种类型的检测 */
if (PyTuple_Check(cls)) {
/* Not a general sequence -- that opens up the road to
recursion and stack overflow. */
if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
return -1;
}
Py_ssize_t n = PyTuple_GET_SIZE(cls);
int r = 0;
for (Py_ssize_t i = 0; i < n; ++i) {
PyObject *item = PyTuple_GET_ITEM(cls, i);
r = object_recursive_isinstance(tstate, inst, item);
if (r != 0) {
/* either found it, or got an error */
break;
}
}
_Py_LeaveRecursiveCall(tstate);
return r;
}
PyObject *checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
if (checker != NULL) {
if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
Py_DECREF(checker);
return -1;
}
PyObject *res = PyObject_CallOneArg(checker, inst);
_Py_LeaveRecursiveCall(tstate);
Py_DECREF(checker);
if (res == NULL) {
return -1;
}
int ok = PyObject_IsTrue(res);
Py_DECREF(res);
return ok;
}
else if (_PyErr_Occurred(tstate)) {
return -1;
}
/* cls has no __instancecheck__() method */
return object_isinstance(inst, cls);
}
static int
object_isinstance(PyObject *inst, PyObject *cls)
{
PyObject *icls;
int retval;
_Py_IDENTIFIER(__class__);
if (PyType_Check(cls)) {
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
if (retval == 0) {
retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
if (icls != NULL) {
if (icls != (PyObject *)(Py_TYPE(inst)) && PyType_Check(icls)) {
retval = PyType_IsSubtype(
(PyTypeObject *)icls,
(PyTypeObject *)cls);
}
else {
retval = 0;
}
Py_DECREF(icls);
}
}
}
else {
if (!check_class(cls,
"isinstance() arg 2 must be a type or tuple of types"))
return -1;
retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
if (icls != NULL) {
retval = abstract_issubclass(icls, cls);
Py_DECREF(icls);
}
}
return retval;
}
PS: PyThreadState
和相关的 _Py_LeaveRecursiveCall
有什么作用。
PS: 代码不可能都能读懂,不着急,慢慢来,一遍一遍捋。