Pin*_*ido 4 python cpython python-internals
我正在研究CPython的代码库。
我想知道在哪里可以找到表中math_sin显示的函数的定义:mathmethodsmathmodule.c
{"sin", math_sin, METH_O, math_sin_doc}
Run Code Online (Sandbox Code Playgroud)
这样做grep "math_sin" -wr的主要cpython文件夹中唯一的回报:
Modules/mathmodule.c: {"sin", math_sin, METH_O, math_sin_doc},
Run Code Online (Sandbox Code Playgroud)
在哪里可以找到此函数的定义?
math_sin通过FUNC1宏定义:
FUNC1(sin, sin, 0,
"sin($module, x, /)\n--\n\n"
"Return the sine of x (measured in radians).")
Run Code Online (Sandbox Code Playgroud)
其中FUNC1定义为:
#define FUNC1(funcname, func, can_overflow, docstring) \
static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
return math_1(args, func, can_overflow); \
}\
PyDoc_STRVAR(math_##funcname##_doc, docstring);
Run Code Online (Sandbox Code Playgroud)
因此预处理器将其扩展为:
static PyObject * math_sin(PyObject *self, PyObject *args) {
return math_1(args, sin, 0);
}
PyDoc_STRVAR(math_sin_doc, "sin($module, x, /)\n--\n\n"
"Return the sine of x (measured in radians).");
Run Code Online (Sandbox Code Playgroud)
(但随后全部放在一行上,并且PyDoc_STRVAR宏也已扩展)
因此,math_sin(module, args)基本上是对math_1(args, sin, 0)和的math_1(args, sin, 0)调用math_1_to_whatever(args, sin, PyFloat_FromDouble, 0),这些调用将验证传入的Python浮点数,将其转换为C double,进行调用sin(arg_as_double),根据需要引发异常,或者将double的返回值sin()与返回之前PyFloat_FromDouble传递的函数包装在一起math_1()结果给呼叫者。
sin()这是POSIX中定义的double sin(double x)函数math.h。
原则上,您可以预处理整个Python源代码树并将输出转储到新目录中;以下内容假定您python已经成功构建了二进制文件,因为它用于为以下文件提取必要的包含标志gcc:
find . -type d -exec mkdir -p /tmp/processed/{} \;
(export FLAGS=$(./python.exe -m sysconfig | grep PY_CORE_CFLAGS | cut -d\" -f2) && \
find . -type f \( -name '*.c' -o -name '*.h' \) -exec gcc -E $FLAGS {} -o /tmp/processed/{} \;)
Run Code Online (Sandbox Code Playgroud)
然后math_sin会出现在中/tmp/preprocessed/Modules/mathmodule.c。
或者,您可以告诉编译器.i使用以下-save-temps标志将预处理器输出保存到文件中:
make clean && make CC="gcc -save-temps"
Run Code Online (Sandbox Code Playgroud)
您会make_sin在中找到Modules/mathmodule.i。