【问题标题】:What do I use instead of PyString_AsString when loading a python module in 3.3在 3.3 中加载 python 模块时,我用什么代替 PyString_AsString
【发布时间】:2014-04-24 15:08:06
【问题描述】:

我正在尝试使用此函数在我的一个 c++ 程序中从 python 加载一个函数

char * pyFunction(void)
{
    char *my_result = 0;
    PyObject *module = 0;
    PyObject *result = 0;
    PyObject *module_dict = 0;
    PyObject *func = 0;
    PyObject *pArgs = 0;

    module = PyImport_ImportModule("testPython");
    if (module == 0)
    {
        PyErr_Print();
        printf("Couldn't find python module");
    }
    module_dict = PyModule_GetDict(module); 
    func = PyDict_GetItemString(module_dict, "helloWorld"); 

    result = PyEval_CallObject(func, NULL); 
    //my_result = PyString_AsString(result); 
    my_result = strdup(my_result);
    return my_result;
}

我应该使用什么来代替 PyString_AsString?

【问题讨论】:

标签: python c++ python-module


【解决方案1】:

如果您使用 PyString_AsString 来获得与 C 兼容的 const char* 表示您所知道的 str 对象,那么在 Py3 中您可以简单地使用 PyUnicode_AsUTF8

    func = PyDict_GetItemString(module_dict, "helloWorld"); 

    result = PyEval_CallObject(func, NULL); 
    const char* my_result = PyUnicode_AsUTF8(result); 

【讨论】:

    【解决方案2】:

    根据您的 helloWorld() 函数返回的类型,它 可能会有所不同,因此最好检查一下。

    要处理返回的str (Python 2 unicode),那么您需要 对其进行编码。编码将取决于您的用例,但我将 使用 UTF-8:

    if (PyUnicode_Check(result)) {
        PyObject * temp_bytes = PyUnicode_AsEncodedString(result, "UTF-8", "strict"); // Owned reference
        if (temp_bytes != NULL) {
            my_result = PyBytes_AS_STRING(temp_bytes); // Borrowed pointer
            my_result = strdup(my_result);
            Py_DECREF(temp_bytes);
        } else {
            // TODO: Handle encoding error.
        }
    }
    

    要处理返回的bytes (Python 2 str),那么你可以得到 直接字符串:

    if (PyBytes_Check(result)) {
        my_result = PyBytes_AS_STRING(result); // Borrowed pointer
        my_result = strdup(my_result);
    }
    

    另外,如果你收到一个非字符串对象,你可以转换它 使用PyObject_Repr()PyObject_ASCII()PyObject_Str()PyObject_Bytes()

    所以最后你可能想要这样的东西:

    if (PyUnicode_Check(result)) {
        // Convert string to bytes.
        // strdup() bytes into my_result.
    } else if (PyBytes_Check(result)) {
        // strdup() bytes into my_result.
    } else {
        // Convert into your favorite string representation.
        // Convert string to bytes if it is not already.
        // strdup() bytes into my_result.
    }
    

    【讨论】:

    • 这是我的python函数: def helloWorld(): returnData = "Hello" return returnData
    • @bbdude95 如果是这种情况,那么result 的类型将是str (PyUnicode),因此仅使用该示例是安全的。但在现实世界的场景中,最好允许不同的类型。
    • 我发现了一些问题。结果字符串周围有引号,\n 也被转换为\\n
    • @ar2015 这就是PyObject_Repr() 所做的事情(repr() 在 Python 方面)。你可能想要PyObject_Str()PyObject_Bytes()
    • @ar2015 是的,进行相同的转换,但使用不同的函数,例如 PyObject_Str()(由于此转换为您提供 unicode,因此您必须先将其编码为字节,如我的第一个示例所示)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 2015-06-05
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    相关资源
    最近更新 更多