如何使用 Python C API 从对象的方法访问常量?

How to access constants from objects' methods with the Python C API?

我有跟进 。这个问题是关于如何访问添加到 Python.

的 C 扩展模块的常量

为了解释这个问题和答案,如果您在初始化函数中向模块添加常量 REDBLUE,如下所示:

PyMODINIT_FUNC
PyInit_mymodule(void)
{
    PyObject* module = PyModule_Create(&Module);

    // ...

    PyModule_AddStringConstant(module, "BLUE", "blue");
    PyModule_AddStringConstant(module, "RED", "red");

    return module;
}

然后您就可以访问它们了,例如从函数中 return 它们,就像这样(请记住,如有必要,您必须增加引用计数):

// Get module dict. This is a borrowed reference.
PyObject* module_dict = PyModule_GetDict(module);

// Get BLUE constant. This is a borrowed reference.
PyObject* BLUE = PyDict_GetItemString(module_dict, "BLUE");

// Get RED constant. This is a borrowed reference.
PyObject* RED = PyDict_GetItemString(module_dict, "RED");

如果您有一个指向模块对象的指针,那将非常有效,链接问题就是这种情况。

我的问题是,如果您没有指向模块对象的指针,您如何做到这一点?例如,如果当前函数是一个对象的方法,那么您拥有的 self 指针是针对该对象的,而不是模块(而且我还没有找到从对象中获取模块的方法):

static PyObject * Foo_get_color(FooObject *self) {
    // How do I get the module object here?
    PyObject *module_dict = PyModule_GetDict(/* ??? */);

    PyObject *color = NULL;
    if (self->color == RED) {
        color = PyDict_GetItemString(module_dict, "RED");
        Py_INCREF(color);
    } else if (self->color == BLUE) {
        color = PyDict_GetItemString(module_dict, "BLUE");
        Py_INCREF(color);
    }

    return color;
}

如果您有模块定义 (struct PyModuleDef),您可以直接调用 PyState_FindModule。我假设你的结构在你的例子中被命名为 Module,所以它看起来像这样:

PyObject * your_function() {
    PyObject *module = PyState_FindModule(&Module);
    PyObject* module_dict = PyModule_GetDict(module);
    ...
}

FindModule documentation表示需要将模块添加到解释器状态如下:

PyMODINIT_FUNC
PyInit_mymodule(void)
{
    PyObject* module = PyModule_Create(&Module);
    PyState_AddModule(module, &Module);
    ...