Python:获取 PyObject 的字符串表示形式?

发布于 2024-10-22 18:26:45 字数 131 浏览 1 评论 0原文

我有一个 C python 扩展,我想打印一些诊断信息。

我收到一个 PyObject* 形式的字符串。

获取该对象的字符串表示形式的规范方法是什么,以便它可以用作 const char * ?

I've got a C python extension, and I would like to print out some diagnostics.

I'm receiving a string as a PyObject*.

What's the canonical way to obtain a string representation of this object, such that it usable as a const char *?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

虐人心 2024-10-29 18:26:45

使用 PyObject_Repr (模仿 Python 的 repr 函数)或 PyObject_Str (模仿 str),然后调用 PyString_AsString 来获取 char * (您可以而且通常应该将其用作 const char*,例如:

PyObject* objectsRepresentation = PyObject_Repr(yourObject);
const char* s = PyString_AsString(objectsRepresentation);

此方法适用于任何 >PyObject。如果您绝对确定 yourObject 是一个 Python 字符串而不是其他东西,例如数字,您可以跳过第一行,只需执行以下操作:

const char* s = PyString_AsString(yourObject);

Use PyObject_Repr (to mimic Python's repr function) or PyObject_Str (to mimic str), and then call PyString_AsString to get char * (you can, and usually should, use it as const char*, for example:

PyObject* objectsRepresentation = PyObject_Repr(yourObject);
const char* s = PyString_AsString(objectsRepresentation);

This method is OK for any PyObject. If you are absolutely sure yourObject is a Python string and not something else, like for instance a number, you can skip the first line and just do:

const char* s = PyString_AsString(yourObject);
扮仙女 2024-10-29 18:26:45

如果您使用的是 Python 3,以下是正确答案:

static void reprint(PyObject *obj) {
    PyObject* repr = PyObject_Repr(obj);
    PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
    const char *bytes = PyBytes_AS_STRING(str);

    printf("REPR: %s\n", bytes);

    Py_XDECREF(repr);
    Py_XDECREF(str);
}

Here is the correct answer if you are using Python 3:

static void reprint(PyObject *obj) {
    PyObject* repr = PyObject_Repr(obj);
    PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
    const char *bytes = PyBytes_AS_STRING(str);

    printf("REPR: %s\n", bytes);

    Py_XDECREF(repr);
    Py_XDECREF(str);
}
三生池水覆流年 2024-10-29 18:26:45

如果您只需要在 Python 3 中打印对象,您可以使用以下函数之一:

static void print_str(PyObject *o)
{
    PyObject_Print(o, stdout, Py_PRINT_RAW);
}

static void print_repr(PyObject *o)
{
    PyObject_Print(o, stdout, 0);
}

If you need just print the object in Python 3 you can use one of these functions:

static void print_str(PyObject *o)
{
    PyObject_Print(o, stdout, Py_PRINT_RAW);
}

static void print_repr(PyObject *o)
{
    PyObject_Print(o, stdout, 0);
}
谁的新欢旧爱 2024-10-29 18:26:45

尝试使用 PyObject_Repr (模仿 Python 的 repr)或 PyObject_Str (模仿 Python 的 str)。

文件:

计算字符串表示形式
对象o。返回字符串
表示成功,NULL 表示
失败。这相当于
Python 表达式 repr(o)。呼叫者
repr() 内置函数。

Try PyObject_Repr (to mimic Python's repr) or PyObject_Str (to mimic Python's str).

Docs:

Compute a string representation of
object o. Returns the string
representation on success, NULL on
failure. This is the equivalent of the
Python expression repr(o). Called by
the repr() built-in function.

丑疤怪 2024-10-29 18:26:45

对于 python >=3.3:

char* str = PyUnicode_1BYTE_DATA(py_object);

是的,这是一个非常量指针,您可以通过它修改(不可变)字符串。

For python >=3.3:

char* str = PyUnicode_1BYTE_DATA(py_object);

Yes, this is a non-const pointer, you can potentially modify the (immutable) string via it.

无所的.畏惧 2024-10-29 18:26:45

PyObject *模块名称;
PyUnicode_AsUTF8(模块名称)

PyObject *module_name;
PyUnicode_AsUTF8(module_name)

梦晓ヶ微光ヅ倾城 2024-10-29 18:26:45

对于任意 PyObject*,首先调用
PyObject_Repr()PyObject_Str() 获取 PyUnicode* 对象。

在 Python 3.3 及更高版本中,调用 PyUnicode_AsUTF8AndSize。除了需要 const char * 的 Python 字符串之外,此函数还需要一个可选地址来存储长度。Python

字符串是具有显式长度字段的对象,可能包含空字节,而 < code>const char* 本身通常是指向以 null 结尾的 C 字符串的指针。将 Python 字符串转换为 C 字符串可能是有损操作。因此,可以从字符串返回 const char* 的所有其他 Python C-API 函数是 已弃用

如果您不介意在字符串恰好包含嵌入的空字节时丢失一堆字符串,则可以为 size 参数传递 NULL 。例如,

PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);

printf("As const char*, ignoring length: %s\n",
    PyUnicode_AsUTF8AndSize(foo, NULL));

打印

As const char*, ignoring length: foo

但是您也可以传入 size 变量的地址,与 const char* 一起使用,以确保您获得整个字符串。

PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);

printf("Including size: ");
size_t size;
const char* data = PyUnicode_AsUTF8AndSize(foo, &size);
fwrite(data, sizeof(data[0]), size, stdout);
putchar('\n');

在我的终端上,输出

$ ./main | cat -v
Including size: foo^@bar

For an arbitrary PyObject*, first call
PyObject_Repr() or PyObject_Str() to get a PyUnicode* object.

In Python 3.3 and up, call PyUnicode_AsUTF8AndSize. In addition to the Python string you want a const char * for, this function takes an optional address to store the length in.

Python strings are objects with explicit length fields that may contain null bytes, while a const char* by itself is typically a pointer to a null-terminated C string. Converting a Python string to a C string is a potentially lossy operation. For that reason, all the other Python C-API functions that could return a const char* from a string are deprecated.

If you do not care about losing a bunch of the string if it happens to contain an embedded null byte, you can pass NULL for the size argument. For example,

PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);

printf("As const char*, ignoring length: %s\n",
    PyUnicode_AsUTF8AndSize(foo, NULL));

prints

As const char*, ignoring length: foo

But you can also pass in the address of a size variable, to use with the const char*, to make sure that you’re getting the entire string.

PyObject* foo = PyUnicode_FromStringAndSize("foo\0bar", 7);

printf("Including size: ");
size_t size;
const char* data = PyUnicode_AsUTF8AndSize(foo, &size);
fwrite(data, sizeof(data[0]), size, stdout);
putchar('\n');

On my terminal, that outputs

$ ./main | cat -v
Including size: foo^@bar
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文