如何在Python中修改Python变量(如reference)的值

2024-09-29 01:24:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为python编写一个syscall包装器(这是一个让我习惯API的有趣项目),
当我开始实现read()时,我对如何修改发送到函数的python缓冲区感到困惑。你知道吗

该函数是read()系统调用的简单cpython包装。
它接受整数(文件描述符)、缓冲区和要读取的最大值,然后返回读取量。你知道吗

除了修改缓冲区外,我的一切都正常:

py_obj py_read(py_obj self, py_obj args){
    char* buff;
    int fd;
    int len;

    if(!PyArg_ParseTuple(args, "isi", &fd, &buff, &len)){
        return NULL;
    }

    return Py_BuildValue("i", read(fd, buff, len));
}

加载模块后,调用read:

>> from syscalls import read
>> STDIN = 1
>> s = ""
>> read(STDIN,s, 256)
napkin
7
>> s
""

虽然这是我所期望的(而且应该是这样,因为我没有实际的参数引用),但我想知道如何获取参数引用。你知道吗

编辑: 在使用@user2357112之后,它仍然不会修改值

>>> b = memoryview(b"")
>>> from syscalls import *
>>> read(1, b, 10)
test
5
>>> b
<memory at 0x7fa060628408>
>>> b.tolist()
[]
>>>

编辑2: 但如果我的尺寸正确的话,它确实可以和bytearray一起使用 谢谢@user2357112


Tags: 函数frompyimportobjreadlenreturn
1条回答
网友
1楼 · 发布于 2024-09-29 01:24:23

你对这个论点有一个引用。实际上,您可能刚刚损坏了argument对象或其周围的内存。您没有对调用者的s变量的引用,但是变量和引用在Python中的工作方式与此不同;引用总是引用对象。你知道吗

Python字符串对象不适合用作可变缓冲区。毕竟,它们应该是不变的。而且,它们是Unicode,read读取字节。相反,请使用大小适当的^{},并使用y*格式代码通过^{}结构查看其内容。你知道吗

另外,由于read返回ssize_t而不是int,因此应该使用n格式代码而不是in对应于Py_ssize_t,当ssize_t存在时,它将匹配ssize_t。你知道吗

PyObject *my_read(PyObject *self, PyObject *args){
    Py_buffer buff;
    int fd;
    int len;

    if(!PyArg_ParseTuple(args, "iy*i", &fd, &buff, &len)){
        return NULL;
    }

    ssize_t read_count = read(fd, buff.buf, len);
    PyBuffer_Release(&buff);

    return Py_BuildValue("n", read_count);
}

相关问题 更多 >