似乎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*
,所以这似乎并没有再次申请)// 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++专家,所以要加一点盐)。
如何获得在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…