IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]4.1.2 格式字符串

    caimouse发表于 2015-10-29 22:28:04
    love 0

    格式字符串是用来指定打包和解包时对数据排列的机制。因此在内部定义了一系列格式字符,通过这些字符来表示数据的类型,另外也定义一些字符来表示数据放入顺序、大小和对齐的方式。

    4.1.2.1 字节顺序、大小和对齐方式

    默认情况下,C语言定义一个结构是按原始格式保存的,包括字节放入顺序,合适填充空白字节,主要根据C语言编译器来决定。在Python语言里,需要在格式字符串前面使用一个字符来表示结构里保存字节的顺序、大小和对齐方式,如下表:

     

    字符

    字节顺序

    大小

    对齐方式

    @

    默认

    默认

    默认

    =

    默认

    标准

    空

    <

    小端模式

    标准

    空

    >

    大端模式

    标准

    空

    !

    网络顺序(=大端模式)

    标准

    空

     

    如果在格式字符串中首字符不是上表任何一个字符,那么系统默认为‘@’模式。默认字节顺序:大端模式或小端模式,是跟python运行在相关主机系统有关。比如在Intel X86和AMD64(X86-64)是使用小端模式来排列,而在Motorola 68000和 PowerPC G5是大端模式来排列。不过在ARM和Intel Itanium上,字节顺序的排列是可以小端模式,也可以是大端模式的,具体视系统设置而定,可以根据sys.byteorder来检查系统的字节顺序排列方式。

     

    默认字节的大小是根据C编译器的sizeof表达式计算出来的大小为准。标准字节的大小是根据字符定义里的大小而定,具体查看后面字符表指定的大小。值得注意是‘@’和‘=’的模式,它们都是使用默认字节顺序,但是‘=’是采用都是标准化的大小和对齐方式。‘!’的模式最适合那些认为不记得网络传送的模式时使用。如果已经知道数据排列方式是大端模式就使用>,如果是小端模式就使用<。

    注意点:

    1. 在结构的字段之间才会填充补齐字符,在结构前面或者后面是不会填充任何补充字符的。

    2. 当使用非默认大小和对齐时,不会填充任何字符,比如处于<,>,=和!模式时。

    3. 为了结构后面以0对齐补充,需要使用特别的格式来指定。具体看例子。

    4.1.2.2 格式字符

    格式字符主要作用是用来规定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 深圳



沪ICP备19023445号-2号
友情链接