3

を使用して Python が C 関数を呼び出すとき

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

呼び出し元、つまり関数とモジュールを知る方法はありますか? これにより、多数のメソッドをディスパッチできる単一のメソッドを持つことができます。呼び出しで文字列名を渡し、その後に引数を渡すなどのハックを考えました。

call ("math", "sin", 2.5)

しかし、これは理想的ではありません。

4

1 に答える 1

4

モジュール + 関数を直接取得することはできませんが、任意の 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 の一部ではないことに注意してください。使用は自己責任で行ってください。

traceback モジュールを使用して Python から同じことを行います。

import traceback

def get_caller_info():
    filename, _, function_name, _ = traceback.extract_stack(limit=2)[1]
    return filename, function_name

この情報は常に信頼できるとは限りません。たとえば、すべてのラムダ関数は named を取得し<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
于 2013-06-05T10:41:21.460 に答える