Python C-API访问字符串常量 [英] Python C-API access String constants

查看:137
本文介绍了Python C-API访问字符串常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用python的C-API在C中实现为python编写的库.在python中,我只需声明以下内容即可在模块中声明常量":

I wanted to implement a library I have written for python in C using the C-API of python. In python I can declare "constants" in my module by just stating:

RED = "red"   # Not really a constant, I know
BLUE = "blue" # but suitable, nevertheless

def solve(img_h):
    # Awesome computations
    return (RED, BLUE)[some_flag]

这些常量随后由模块提供的函数返回.我在C语言中做同样的事情遇到了麻烦.这是到目前为止我得到的:

Those constants are then later returned by the functions offered by the module. I have some trouble doing the same thing in C. Here is what I got so far:

PyMODINIT_FUNC
PyInit_puzzler(void)
{
    PyObject* module = PyModule_Create(&Module);
    (void) PyModule_AddStringConstant(module, "BLUE",   "blue");
    (void) PyModule_AddStringConstant(module, "RED",    "red");
    return module;
}

PyObject* solve(PyObject* module, PyObject* file_handle)
{
    // Do some awesome computations based on the file
    // Involves HUGE amounts of memory management, thus efficient in C
    // PROBLEM: How do I return the StringConstants from here?
    return some_flag ? BLUE : RED;
}

我已经标记了有问题的部分.用PyModule_AddStringConstant(module, "FOO", "foo");将字符串常量添加到模块中后,如何从我的方法中以PyObject*的形式返回它们呢?返回它们时,我是否需要增加引用计数器?

I have already marked the problematic part. After I add string constants to the module with PyModule_AddStringConstant(module, "FOO", "foo"); how can I actually return them as a PyObject* from my methods? Do I need to increase the ref-counter when I return them?

推荐答案

由于 PyDict_GetItemString( dict,key)这是从模块中访问常量(定义之后)的方式:

Since PyModule_AddStringConstant(module, name, value) adds the constant to the module, it should be available from the module's dictionary which can be acquired with PyModule_GetDict(module). You can then access any attribute from the module via its dictionary using PyDict_GetItemString(dict, key) This is how you can access the constants from your module (after their definitions):

// 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");

要将其与您的solve()函数一起使用,您需要类似以下内容:

To put this into context with your solve() function, you want something similar to:

PyObject* solve(PyObject* module, PyObject* file_handle)
{
    // Do some awesome computations based on the file
    // Involves HUGE amounts of memory management, thus efficient in C

    // Return string constant at the end.
    PyObject* module_dict = PyModule_GetDict(module);
    PyObject* constant = NULL;
    if (some_flag) {
        // Return BLUE constant. Since BLUE is a borrowed 
        // reference, increment its reference count before 
        // returning it.
        constant = PyDict_GetItemString(module_dict, "BLUE");
        Py_INCREF(constant);
    } else {
        // Return RED constant. Since RED is a borrowed 
        // reference, increment its reference count before 
        // returning it.
        constant = PyDict_GetItemString(module_dict, "RED");
        Py_INCREF(constant);
    }

    // NOTE: Before you return, make sure to release any owned
    // references that this function acquired. `module_dict` does
    // not need to be released because it is merely "borrowed".

    // Return the constant (either BLUE or RED) as an owned
    // reference. Whatever calls `solve()` must make sure to
    // release the returned reference with `Py_DECREF()`.
    return constant;
}

这篇关于Python C-API访问字符串常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆