字节对象是immutable。它不支持项目分配:
>>> bar = b"bar"
>>> bar[0] = b"#"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment
str对象也是不可变的:
^{pr2}$可以用ctypes修改bytes对象,而不能用str对象修改bytes对象。你能解释一下为什么吗?请看下面的例子。在
c代码
char* foo(char *bar) {
bar[0] = '#';
return bar;
}
c代码编译
gcc -shared -o clib.so -fPIC clib.c
python代码
import ctypes
clib = ctypes.CDLL('./clib.so')
bar = b"bar"
print("Before:", bar, id(bar))
clib.foo(bar)
print("After: ", bar, id(bar))
python代码输出
Before: b'bar' 140451244811328
After: b'#ar' 140451244811328
str对象在python3中也是不可变的,但与bytes对象不同,它不可能用ctypes修改它。在
python代码
import ctypes
clib = ctypes.CDLL('./clib.so')
bar = "bar"
print("Before:", bar, id(bar))
clib.foo(bar)
print("After: ", bar, id(bar))
python代码输出
Before: bar 140385853714080
After: bar 140385853714080
python3中的
str
抽象为Unicode,根据字符串中使用的最高Unicode字符,可以将其存储为每个字符串1、2或4字节。要将字符串传递给C函数,必须将其转换为特定的表示形式。ctypes
在本例中,将转换后的临时缓冲区传递给C而不是原始缓冲区。ctypes
如果函数原型不正确,或者将不可变对象发送给改变内容的函数,那么Python可能会崩溃和损坏,在这种情况下,用户需要小心。在在
bytes
的情况下,ctypes
会传递一个指向其内部字节缓冲区的指针,但并不期望它被修改。考虑:由于}中存储相同的引用。如果您将
bytes
是不可变的,Python可以在a
和{b
传递给ctypes
包装的函数,并且它修改了它,它也可能损坏a
。在直接从ctypes documentation开始:
相关问题 更多 >
编程相关推荐