python - 调用 C 函数。是谁打来的

标签 python

当 python 使用 C 函数调用时

static PyObject* Myfunction (PyObject *self, PyObject *args)

有没有办法知道调用者是谁,即函数和模块?这将允许我拥有一个可以分派(dispatch)大量方法的方法。我想到了一个 hack,比如在调用中传递字符串名称,然后是参数,例如

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)
}

请注意,框架对象结构不是公共(public) API 的一部分,使用风险自负。

使用追溯模块从 Python 完成同样的事情:

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

关于python - 调用 C 函数。是谁打来的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16933418/

相关文章:

python - 准确的二值图像分类

python - 在使用 conda 创建的不同环境中切换 jupyter 笔记本时遇到问题

python - 如何使用Python中的类函数隐藏按钮

python - 如何孵化 PolyCollection 实例?

python - 多次点击按钮调用函数?

python - 退出函数在带有 python 的 OpenCV 中不起作用

python - 数据未显示在 pyqt UI 中

python - 优雅的解析这个? "a,b,c",d ,"e,f"

python - 多维数组上的 Numpy 直方图

带有标志的 Python re.sub 不会替换所有出现