9

I wanted to pad a string with null characters ("\x00"). I know lots of ways to do this, so please do not answer with alternatives. What I want to know is: Why does Python's string.format() function not allow padding with nulls?

Test cases:

>>> "{0:\x01<10}".format("bbb")
'bbb\x01\x01\x01\x01\x01\x01\x01'

This shows that hex-escaped characters work in general.

>>> "{0:\x00<10}".format("bbb")
'bbb       '

But "\x00" gets turned into a space ("\x20").

>>> "{0:{1}<10}".format("bbb","\x00")
'bbb       '
>>> "{0:{1}<10}".format("bbb",chr(0))
'bbb       '

Even trying a couple other ways of doing it.

>>> "bbb" + "\x00" * 7
'bbb\x00\x00\x00\x00\x00\x00\x00'

This works, but doesn't use string.format

>>> spaces = "{0: <10}".format("bbb")
>>> nulls  = "{0:\x00<10}".format("bbb")
>>> spaces == nulls
True

Python is clearly substituting spaces (chr(0x20)) instead of nulls (chr(0x00)).

4

3 回答 3

4

深入研究 Python 2.7 的源代码,我发现问题出在本节中./Objects/stringlib/formatter.h,第 718-722 行(在 2.7.3 版中):

/* Write into that space. First the padding. */
p = fill_padding(STRINGLIB_STR(result), len,
                 format->fill_char=='\0'?' ':format->fill_char,
                 lpad, rpad);

问题是当没有指定填充字符时,零/空字符 ( '\0') 被用作默认值。这是为了启用此行为:

>>> "{0:<10}".format("foo")
'foo       '

可以在at中设置format->fill_char = ' ';为默认值,但有一些关于向后兼容性的信息,稍后会检查。无论如何,我的好奇心得到了满足。如果其他人的答案比这有更多的历史或更好的解释,我会接受它。parse_internal_render_format_spec()./Objects/stringlib/formatter.h:186'\0'

于 2013-05-24T19:57:27.427 回答
2

原始问题的答案是它是python中的一个错误。

它被记录为被允许的,但不是。它于 2014 年修复。对于 python 2,修复首先出现在 2.7.7 或 2.7.8 中(我不知道如何分辨)

原始跟踪问题

于 2016-05-17T17:27:26.390 回答
0

因为string.formatPython2.7 中的方法是 Python3 的反向移植string.format。Python2.7 unicode 是 Python 3 字符串,其中 Python2.7 字符串是 Python3 字节。在 Python3 中,字符串是表示二进制数据的错误类型。您将使用没有格式方法的字节。所以你真的应该问为什么format在 2.7 中使用 string 的方法实际上应该只使用 unicode 类型,因为这就是 Python3 中的字符串。

我想答案是那里太方便了。

作为一个相关的问题,为什么还没有format字节

于 2013-05-24T19:39:49.397 回答