Python C API的常量正确性 [英] Const correctness of Python's C API

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

问题描述

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

It seems that the Python C API is not consistent with the const correctness of character arrays. For example, PyImport_ImportFrozenModule accepts a char*, whereas PyImport_ImportModule accepts a const char*.

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

The implication of all this is that in my C++ application that I am writing with an embedded Python interpreter, I sometimes have to cast the string literal that I pass to a Python API call as just a char* (as opposed to const char*), and sometimes I don't. For example:

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*的编译器警告.

If I don't do the const_cast<char*> (or (char*)) on the string literal, I get a compiler warning about casting string literals to char*.

这是我的问题:

  1. 让某些函数不使用const char*是否有优势/原因(和/或Python API为什么与此不一致)?我的理解是,如果函数可以采用字符串文字,那么它就不能更改char*,因此const修饰符只会加强此功能.我还相信const区别对C(为API编写了该语言)不如在C ++中重要(如果我错了,请纠正我……我的强项是python,而不是C/C ++).是否因为在C语言中不那么重要而缺少Python API的常量正确性"? (在python邮件列表上有一个旧线程从2000年开始问同样的问题,但它似乎没什么用,这暗示原因可能是由于某些编译器不支持const.由于许多函数现在都具有const char*,因此这似乎不适用不再)
  2. 因为我对C ++的理解有限,所以我不确定是否要正确地转换字符串文字.从我的角度来看,我可以选择以下任一选项(我目前正在执行第一个操作):

  1. Is there an advantage/reason to having some of the functions not take a const char* (and/or why would the Python API not be consistent in this)? My understanding is that if the function can take a string literal, it cannot change the char* so the const modifier would just be reinforcing this. I also believe that the const distinction is not as important for C (for which the API was written) than it is in C++ (correct me if I am wrong... my strength is python, not C/C++). Is the lack of "const correctness" of the Python API because it's simply not as important in C? (There is an old thread on the python mailing list from 2000 asking the same question, but it didn't seem to go anywhere and it is implied the reason might be due to some compilers not supporting const. Since many functions now have const char*, this doesn't seem to apply anymore)
  2. Because my understanding of C++ is limited, I am unsure if I am going about casting string literals properly. The way I see it, I can either one of the following (I am currently doing the first):

// 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*的函数,例如

It looks like the Python3 branch is slowly trying to fix the const correctness issue. For example, the PyImport_ImportFrozenModule function I use as an example above now takes a const char* in Python 3.4, but there are still functions that take only a char*, such as PyLong_FromString.

推荐答案

基于python-dev中的一些邮件列表对话,看起来最初的API只是没有考虑到const正确性而创建,可能只是因为Guido没想到.一直追溯到2002年,有人问,通过添加const-correctness来解决这个问题,抱怨总是必须这么做:

Based on some mailing list conversations from python-dev, it looks like the initial API just simply wasn't created with const correctness in mind, probably just because Guido didn't think about it. Dating all the way back to 2002, someone asked if there was any desire to address that by adding const-correctness, complaining that it's a pain to always have to do this:

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

Guido Van Rossum(Python的创建者)已回复(重点是我的):

Guido Van Rossum (the creator of Python) replied (emphasis mine):

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

I've never tried to enforce const-correctness before, but I've heard enough horror stories about this. The problem is that it breaks 3rd party extensions left and right, and fixing those isn't always easy. In general, whenever you add a const somewhere, it ends up propagating to some other API, which then also requires a const, which propagates to yet another API needing a const, ad infinitum.

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

There was a bit more discussion, but without Guido's support the idea died.

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

Fast forward nine years, and the topic came up again. This time someone was simply wondering why some functions were const-correct, while others weren't. One of the Python core developers replied with this:

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

We have been adding const to many places over the years. I think the specific case was just missed (i.e. nobody cared about adding const there).

似乎可以在不破坏向后兼容性的情况下做到这一点,在C API中的很多地方都添加了const-correctness(对于Python 3,在将要使用的地方打破了与Python 2的向后兼容性),但从未真正真正地在全球范围内对其进行修复.因此,在Python 3中情况要好一些,但是即使到现在,整个API仍可能无法正确校正.

It seems that when it could be done without breaking backwards compatibility, const-correctness has been added to many places in the C API (and in the case of Python 3, in places where it would break backwards compatibility with Python 2), but there was never a real global effort to fix it everywhere. So the situation is better in Python 3, but the entire API is likely not const correct even now.

我认为Python社区没有任何首选的方式来处理不符合const要求的调用的转换(官方

I'm don't think that the Python community has any preferred way to handle casting with calls that are not const-correct (there's no mention of it in the official C-API style guide), probably because there aren't a ton of people out there interfacing with the C-API from C++ code. I would say the preferred way of doing it from a pure C++ best-practices perspective would be the first choice, though. (I'm by no means a C++ expert, so take that with a grain of salt).

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

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