Python C API的常量正确性 - python

似乎Python C API与字符数组的const正确性不一致。例如,PyImport_ImportFrozenModule接受char*,而PyImport_ImportModule接受const char*

所有这些的含义是,在使用嵌入式Python解释器编写的C++应用程序中,有时我必须将传递给Python API调用的字符串文字转换为char*(而不是const char*),有时我不。例如:

PyObject *os = PyImport_ImportModule("os"); // Works without the const_cast
PyObject *cwd = PyObject_CallMethod(os, const_cast<char*>("getcwd"), NULL); // Accepts char*, not const char*

如果不对字符串文字执行const_cast<char*>(或(char*)),则会收到有关将字符串文字强制转换为char*的编译器警告。

这是我的问题:

  • 使某些函数不采用const char*是否有优势/原因(和/或为什么Python API在此方面会不一致)?我的理解是,如果函数可以采用字符串文字,那么它就不能更改char*,因此const修饰符只会加强此功能。我还相信const的区别对C(为其编写API)对C的重要性不如对C++的重要(如果我错了,请纠正我……我的强项是python,而不是C / C++)。是否因为在C语言中不那么重要而缺少Python API的“常量正确性”? (从2000年开始就有一个old thread on the python mailing list提出了同样的问题,但是它似乎没有走到任何地方,这暗示着原因可能是由于某些编译器不支持const。由于许多函数现在都具有const char*,所以这似乎并没有再次申请)
  • 因为我对C++的理解有限,所以我不确定是否要正确地转换字符串文字。以我的方式看,我可以选择以下任一方法(我目前正在做第一个操作):
    // Method 1) Use const_cast<char*>
    PyImport_ImportFrozenModule(const_cast<char*>("mymodule"));
    
    // Method 2) Use (char*)
    PyImport_ImportFrozenModule((char*) "mymodule");
    
    // Method 3) Use char array
    char mod[] = "mymodule";
    PyImport_ImportFrozenModule(mod);
    

    使用哪种最佳方法?

  • 更新:

    看来Python3分支正在慢慢尝试解决const正确性问题。例如,我在上面的示例中使用的PyImport_ImportFrozenModule函数现在在Python 3.4中采用了const char*,但是仍然有一些仅采用char*的函数,例如PyLong_FromString。

    参考方案

    根据python-dev的一些邮件列表对话,看起来最初的API只是在创建时就没有考虑到const正确性,可能是因为Guido并未考虑到它。可以追溯到2002年,如果想通过添加const-correctness来解决这个问题,请someone asked抱怨总是必须这样做:

    somefunc(const char* modulename, const char* key)
    {
        ... PyImport_ImportModule(const_cast<char*>(modulename)) ...
    

    Guido Van Rossum(Python的创建者)replied(强调我的):

    我从未尝试过在之前强制执行const-correctness,但是我听说过
    足够的恐怖故事。问题是它打破了第三
    左右方扩展,修复这些扩展并不总是那么容易。
    通常,每当您在某个位置添加const时,它最终都会传播
    到其他一些API,然后还需要一个const,
    到另一个需要const的API。

    进行了更多讨论,但是在Guido的支持下,这个想法死了。

    快进九年了,这个话题又来了。这次,有人只是想知道为什么某些函数是const正确的,而其他函数却不是。 Python核心开发人员之一replied with this:

    多年来,我们一直在许多地方添加const。我觉得
    只是错过了特定情况(即没有人关心添加const
    那里)。

    似乎可以在不破坏向后兼容性的情况下做到这一点,在C API中的很多地方都添加了const-correctness(对于Python 3,它会破坏与Python 2的向后兼容性),但是在那里在任何地方进行修复从来都不是真正的全球努力。因此,在Python 3中情况要好一些,但是即使到现在,整个API仍可能无法正确校正。

    我不认为Python社区有任何首选的方式来处理不是const -correct的调用的强制转换(官方C-API style guide中没有提及它),可能是因为那里没有很多人通过C++代码与C-API接口。我会说,从纯C++最佳实践的角度来看,这样做的首选方法将是首选。 (我绝不是C++专家,所以要加一点盐)。

    获取用于自定义搜索的cx ID,Google API-Python - python

    如何获得在Python中使用自定义搜索API的通用cx ID?http://code.google.com/p/google-api-python-client/source/browse/samples/customsearch/main.py从我的阅读中我了解到,此cx ID仅适用于某些网站(当创建自定义搜索引擎时,它会询问我特定的网站),但是我希望它在…

    Python uuid4,如何限制唯一字符的长度 - python

    在Python中,我正在使用uuid4()方法创建唯一的字符集。但是我找不到将其限制为10或8个字符的方法。有什么办法吗?uuid4()ffc69c1b-9d87-4c19-8dac-c09ca857e3fc谢谢。 参考方案 尝试:x = uuid4() str(x)[:8] 输出:"ffc69c1b" Is there a way to…

    Python:无法识别Pip命令 - python

    这是我拍摄的屏幕截图。当我尝试在命令提示符下使用pip时,出现以下错误消息:pip无法识别为内部或外部命令,可操作程序或批处理文件。我已经检查了这个线程:How do I install pip on Windows?我所能找到的就是我必须将"C:\PythonX\Scripts"添加到我的类路径中,其中X代表python版本。如您在我的…

    Python GPU资源利用 - python

    我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…

    Python:如何将有效的uuid从String转换为UUID? - python

    我收到的数据是 { "name": "Unknown", "parent": "Uncategorized", "uuid": "06335e84-2872-4914-8c5d-3ed07d2a2f16" }, 我需要将uuid从Strin…