pformat() 输出的缩进

Fer*_*dox 7 python python-3.x pprint

我有一个函数,用于pformat()将字典转换为字符串(无关:字符串稍后将插入到文件write().py)。

所以MY_DCT = {1: 11, 2: 22, 3: 33}会变成这样的字符串:

MY_DCT = {
    1: 11,
    2: 22,
    3: 33}
Run Code Online (Sandbox Code Playgroud)

该功能有2个要求:

  1. 字典项目必须显示在第一行之后。
  2. 元素必须缩进 4 个空格。

这是函数:

import pprint    

def f(obj_name, obj_body_as_dct):

    body = '{\n' + pprint.pformat(obj_body_as_dct, indent=4, width=1)[1:]
    name_and_equal_sign = obj_name + ' = '

    return name_and_equal_sign + body + '\n\n'


d = {1: 11, 2: 22, 3: 33}

print(f('MY_DCT', d))
Run Code Online (Sandbox Code Playgroud)

如果indent=0我得到这个字符串:

MY_DCT = {
1: 11,
2: 22,
3: 33}
Run Code Online (Sandbox Code Playgroud)

如果indent=4我得到这个字符串:

MY_DCT = {
   1: 11,
    2: 22,
    3: 33}
Run Code Online (Sandbox Code Playgroud)

我检查了参数pformat()但不知道如何使每行上出现正确数量的空格。

我知道我可以使用replace()+' '来修复字符串,但我想知道额外的空白从何而来,以及我是否可以通过正确设置参数来摆脱它(如果可能的话)。

注意:如果有更好的方法来实现上述目的,请告诉我。

Fer*_*dox 5

indentin的默认值为pformat1,因此键会一个接一个地出现。

例如,pformat(d, indent=0, width=1)将产生以下字符串:

{1: 11,
2: 22,
3: 33}
Run Code Online (Sandbox Code Playgroud)

indent=1:

{1: 11,
 2: 22,
 3: 33}
Run Code Online (Sandbox Code Playgroud)

indent=2

{ 1: 11,
  2: 22,
  3: 33}
Run Code Online (Sandbox Code Playgroud)

第一行始终少一个空格。


由于目标是在第一行之后显示 dict 元素,并且所有元素缩进 4 个空格,因此在第一个元素之前添加一个空格并使用indent=4将适用于某些 dict(如 @logic 所建议)。

然而像这样的字典d = {1: {'a': 1, 'b': 2}, 2: 22, 3: 33}看起来相当难看,因为indent也会影响深度大于 1 的字典的外观:

MY_DCT = {
    1: {   'a': 1,
           'b': 2},
    #    ^
    #    |
    # ugly
    2: 22,
    3: 33}
Run Code Online (Sandbox Code Playgroud)

最吸引人的解决方案(对于我正在处理的数据)是indent=1为第一个元素保留并添加 3 个空格,为其余元素添加 4 个空格。

def f(obj_name, given_dct):
    """
    Converts given dct (body) to a pretty formatted string.
    Resulting string used for file writing.

    Args:
        obj_name: (str) name of the dict
    Returns:
        (str)
    """

    string = pp.pformat(given_dct, width=1)[1:]

    new_str = ''
    for num, line in enumerate(string.split('\n')):
        if num == 0:
            # (pprint module always inserts one less whitespace for first line)
            # (indent=1 is default, giving everything one extra whitespace)
            new_str += ' '*4 + line + '\n'
        else:
            new_str += ' '*3 + line + '\n'

    return obj_name + ' = {\n' + new_str


s = f(obj_name='MY_DCT', given_dct=d)
Run Code Online (Sandbox Code Playgroud)

结果是这个字符串:

MY_DCT = {
    1: {'a': 'aa',
        'b': [1,
              2,
              3]},
    2: 22,
    3: 33}
Run Code Online (Sandbox Code Playgroud)