[Module]Struct Module学习(待续)

简述

Python的struct模块被用来转换为字节为单位的binary数据。即实现Python数值和C语言中的字节数据之间的转换。Python好像也提供了bytes对象。
字节数据在binary文件存取,网络连接中会使用比较多。将C结构体转为Python时(称为packing?),因为C结构中会有字节对齐的问题,所以转为Python也要注意做padding,而在将Python转换为C结构体(unpacking)时也要注意该问题。
有几个struct模块的函数使用了buffer这个参数,这说明该对象实现了Buffer Protocol,用于提供readable或read-writable的buffer。这个Buffer Protocol可能是在C一层实现的了。

Buffer Protocol

Python有时需要一些底层的array或buffer的结构,像bytes, bytearray这样的对象,还有array.array。从上层来讲,如果能直接访问这样的buffer,避免许多不必要的拷贝,在一些图像,数据分析等方面是很有用的。而Buffer Protocol就是在C这一层为满足Python这样的需求而设计的。

Protocol Sides

其实是该Protocol涉及的两个使用角色:

  • 生产者端:导出buffer interface,暴露底层buffer的信息;
  • 消费者端:提供了多种方法来获取底层raw data的指针(引用?);
    简单例子像bytes, bytearray,将它们底层的buffer以字节流的形式导出来。
    file对象的write()方法就是一个典型的buffer interface的消费者。file对象可以通过buffer interface导出字节流,继而写入文件。
    buffer interface的消费者端有两种方式获取一个buffer:
  • PyObject_GetBuffer()
  • PyArg_ParseTuple()
    当buffer不再需要时,都需要显示的调用PyBuffer_Release()来释放掉,否则很容易招致内存泄漏。

Buffer structure

buffer structure可以以binary数据的格式暴露一个对象,即提供了一种从memory的角度来访问对象的方式(初步这样理解)。
buffer其实是C结构,而非PyObject指针。
Py_buffer:
- void *buf: 指向buffer空间的指针;
- void *obj: 导出对象的新引用;
- Py_ssize_t len: product(shape) * itemsize,即底层memory空间的大小,当然如果不是数据结构的话,memory空间有可能是不连续的;
- int readonly: 标识该buffer是否是read-only;
- Py_ssize_t itemsize: 单个元素的字节数,数值和struct.calcsize()相同;
- const char *format: 一个NUL停止符;
- int ndim: 多维数组的维数;
- Py_ssize_t shape: shape[0] … * shape[ndim-1] * itemsize = len;
- Py_ssize_t *strides: 可以是任意整数;
- Py_ssize_t *suboffsets:
- void *internal: 内部使用

Buffer相关函数

  • int PyObject_CheckBuffer(PyObject *obj): 检查Object是否支持buffer interface,支持则返回1,否则返回0;
  • int PyObject_GetBuffer(PyObject *exporter, Py_buffer *view, int flags): 想exporter请求buffer;
  • void PyBuffer_Release(Py_buffer *view): 释放上面get到的buffer;
  • Py_ssize_t PyBuffer_SizeFromFormat(const char *) : 该函数尚未实现……;
  • int PyBuffer_IsContiguous(Py_buffer *view, char order): memory是否连续,连续返回1,否则返回0;
  • void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char order) :
  • int PyBuffer_FillInfo(Py_buffer *view, PyObject *exporter, void *buf, Py_ssize_t len, int readonly, int flags)

struct Exceptions

struct.error

struct functions

  • struct.pack(fmt, v1, v2, …) : 根据格式化字符串fmt进行packing,返回一个包含v1,v2的字节对象;
  • struct.pack_into(fmt, buffer, offset, v1, v2, …) : 根据格式化字符串fmt将v1, v2进行packing,然后将packing后的字节流写入到buffer的以offset位置开始的地方;
  • struct.unpack(fmt, buffer) :

你可能感兴趣的:([Module]Struct Module学习(待续))