格式字符串是用来指定打包和解包时对数据排列的机制。因此在内部定义了一系列格式字符,通过这些字符来表示数据的类型,另外也定义一些字符来表示数据放入顺序、大小和对齐的方式。
默认情况下,C语言定义一个结构是按原始格式保存的,包括字节放入顺序,合适填充空白字节,主要根据C语言编译器来决定。在Python语言里,需要在格式字符串前面使用一个字符来表示结构里保存字节的顺序、大小和对齐方式,如下表:
字符 | 字节顺序 | 大小 | 对齐方式 |
@ | 默认 | 默认 | 默认 |
= | 默认 | 标准 | 空 |
< | 小端模式 | 标准 | 空 |
> | 大端模式 | 标准 | 空 |
! | 网络顺序(=大端模式) | 标准 | 空 |
如果在格式字符串中首字符不是上表任何一个字符,那么系统默认为‘@’模式。默认字节顺序:大端模式或小端模式,是跟python运行在相关主机系统有关。比如在Intel X86和AMD64(X86-64)是使用小端模式来排列,而在Motorola 68000和 PowerPC G5是大端模式来排列。不过在ARM和Intel Itanium上,字节顺序的排列是可以小端模式,也可以是大端模式的,具体视系统设置而定,可以根据sys.byteorder来检查系统的字节顺序排列方式。
默认字节的大小是根据C编译器的sizeof表达式计算出来的大小为准。标准字节的大小是根据字符定义里的大小而定,具体查看后面字符表指定的大小。值得注意是‘@’和‘=’的模式,它们都是使用默认字节顺序,但是‘=’是采用都是标准化的大小和对齐方式。‘!’的模式最适合那些认为不记得网络传送的模式时使用。如果已经知道数据排列方式是大端模式就使用>,如果是小端模式就使用<。
注意点:
1. 在结构的字段之间才会填充补齐字符,在结构前面或者后面是不会填充任何补充字符的。
2. 当使用非默认大小和对齐时,不会填充任何字符,比如处于<,>,=和!模式时。
3. 为了结构后面以0对齐补充,需要使用特别的格式来指定。具体看例子。
格式字符主要作用是用来规定C语言数据类型与Python数据类型进行转换的标准。标准大小这一列说明当使用这种方式打包时占用字节空间的大小,并且只有在<,>,=和!模式时才起作用,至于使用默认方式是根据不同系统平台来决定的。
格式 | C类型 | Python类型 | 标准大小 | 注意 |
x | 填充字节 | 没有值 |
|
|
c | char | bytes对象长度为1 | 1 |
|
b | signed char | integer | 1 | (1),(3) |
B | unsigned char | integer | 1 | (3) |
? | _Bool | bool | 1 | (1) |
h | short | integer | 2 | (3) |
H | unsigned short | integer | 2 | (3) |
i | int | integer | 4 | (3) |
I | unsigned int | integer | 4 | (3) |
l | long | integer | 4 | (3) |
L | unsigned long | integer | 4 | (3) |
q | long long | integer | 8 | (2), (3) |
Q | unsigned long long | integer | 8 | (2), (3) |
n | ssize_t | integer |
| (4) |
N | size_t | integer |
| (4) |
f | float | float | 4 | (5) |
d | double | float | 8 | (5) |
s | char[] | bytes |
|
|
p | char[] | bytes |
|
|
P | void * | integer |
| (6) |
注意:
1. ‘?’字符表示C99的_Bool类型,如果不存在此类型,可以使用 char类型来表示。在标准模式时,占用大小总是1个字节。
2. ‘q’和‘Q’字符使用时需要注意仅当此平台的C编译器支持C语言的long long或在Windows平台上支持__int64类型时,默认模式才可以使用它们。在标准模式时,不受此点限制,总是可以使用。
3. 当尝试转换非整数类型转换为整数时,并且非整数类型定义方法:__index__()时,会先调用此方法,把此方法返回的整数进行打包。
4. ‘n’和‘N’仅在默认大小模式下起作用,也就是默认格式字符或者设置为‘@’时。如果在标准大小模块选择其它合适格式来使用。
5. ‘f’和‘d’转换,仅支持IEEE754的32位和64位二进制表示方式,而不会考虑平台的浮点数处理方式。
6. ‘P’转换方式仅在默认模式起作用。如果选择‘=’模式时根据系统来决定大端模式还是小端模式,因此本模块不会使用它来作判断大小端模式。
为了简化多个重复格式字符,可以使用这种方式来表示:4h表示hhhh,这种两种方式是等价的。如果在格式字符之间有空格字符,则会忽略它们;因而数字与格式字符之间不能出现空格。
不过,对于格式字符‘s’来说有点特别了,在它前面数字不是表示多少个数组,而是表示数组的长度。比如‘10s’表示10个字符的数组。同样‘10c’表示10个字符。如果在‘s’和‘c’前面没有数字出现,默认都是表示一个字节。这样在打包字符串时,就会根据这个长度来截断或填充字符达到指定长度,而在解包时总是读取指定长度的字符。还有一种特殊的情况,当‘s’和‘c’前面指定的数字为0时,都表示空串,0个字符。
‘p’模式是表示使用Pascal语言表示字符串的方式,意思是指使用第一个字节表示字符串的长度,第二字节起表示字符串的内容,如果后面不足够长度时使用0等字符补充。在首字节里保存字符串内容的大小,如果超过255字符,就保存为255。如果按这种格式打包时,当给出来的字符串超出255时,只会保存255个字符。如果字符串的实际长度比指定的长度小,那么在字符串后面补充空字符。在解包时,总是根据获取指定长度的大小,但不会超过255个字符。
‘?’字符在打包模式时会根据参数对象来判断写入0或1(或者大于1)的值;在解包时,任何非0的值都会认为是真值。
蔡军生 QQ:9073204 深圳