当 python 调用 C 函数时使用
static PyObject* Myfunction (PyObject *self, PyObject *args)
有没有办法知道调用者是谁,即函数和模块?这将允许我拥有一个可以调度大量方法的方法。我想到了一种技巧,例如在调用中传递字符串名称,后跟参数,例如
call ("math", "sin", 2.5)
但这并不理想。
当 python 调用 C 函数时使用
static PyObject* Myfunction (PyObject *self, PyObject *args)
有没有办法知道调用者是谁,即函数和模块?这将允许我拥有一个可以调度大量方法的方法。我想到了一种技巧,例如在调用中传递字符串名称,后跟参数,例如
call ("math", "sin", 2.5)
但这并不理想。
您不能直接获取模块 + 函数,但您可以获取任何 Python(解释)堆栈帧的文件名和函数名。
函数返回一个带有调用者文件名和函数名的元组使用 C API:
#include <frameobject.h>
static PyObject* get_caller_info(PyObject *self, PyObject *args) {
PyCodeObject* code = PyEval_GetFrame()->f_code;
return Py_BuildValue("(OO)", code->co_filename, code->co_name)
}
请注意,框架对象结构不是公共 API 的一部分,使用风险自负。
在 Python 中使用 traceback 模块完成了同样的事情:
import traceback
def get_caller_info():
filename, _, function_name, _ = traceback.extract_stack(limit=2)[1]
return filename, function_name
此信息可能并不总是可靠的。例如,所有 lambda 函数都被命名为<lambda>
.
要从文件名中获取模块模块实例,您可以像这样创建缓存:
_filename_to_module = {os.path.realpath(module.__file__): module
for module in sys.modules.itervalues()
if hasattr(module, '__file__')}
module = _filename_to_module.get(filename)
if module is None:
# refresh the cache and retry