pformat() 输出的缩进

Indentation of pformat() output

我有一个使用 pformat() 将字典转换为字符串的函数(不相关:稍后将在 write() 中插入字符串 .py 文件)。

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

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

函数有两个要求:

  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))

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

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

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

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

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

我知道我可以使用 replace()+' ' 等来修复字符串,但我想知道多余的空格是从哪里来的,我是否可以通过正确设置来摆脱它参数(如果可能的话)。

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

参数不是您打印的问题。添加换行符 ('\n') 时会出现问题。从这个例子可以看出:

import pprint    

def f(obj_name, obj_body_as_dct):

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

    return '"""' + name_and_equal_sign + body + '"""' + '\n\n'


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

print(f('MY_DCT', d))

这输出:

"""MY_DCT = 
{   1: 11,
    2: 22,
    3: 33}"""

换行符和在打印的第一行中添加“{”是为什么只有第一行的输出似乎被一个小的 space 偏移了。

更新#1

在对这些值进行一些修改之后,我能够匹配您想要的输出:

import pprint    

def f(obj_name, obj_body_as_dct):

    body = pprint.pformat(obj_body_as_dct, indent=4, width=1, depth=1)[1:]
    name_and_equal_sign = obj_name 

    return '"""' + name_and_equal_sign + ' = ' + '{' + '\n ' + body +'"""'  + '\n\n'  
                                                        # ^ I added a space in this newline

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

print(f('MY_DCT', d))

以上代码输出:

"""MY_DCT = { 
    1: 11,
    2: 22,
    3: 33}"""

所以,本质上,你只需要一个换行符中的 space(如代码所示)。

更新 #2:

按照您在评论中的建议:

Try this: print(pp.pformat({1:11, 2:22, 3:33}, indent=0, width=1)), with indent going from 0 to 2. You ll notice, it applies one less whitespace on the first line. It is the way pformat() is built. -@user 5061

我试过这个:

import pprint as pp

for i in range(0,3):
    print(pp.pformat({1:11, 2:22, 3:33}, indent=i, width=1))

它给了我这个输出:

{1: 11,     #Indent = 0 Each entry (except 1) is indented by 0 spaces, because the "{" operator is in the way. 
2: 22,
3: 33}
{1: 11,     #Indent = 1 Each entry is indented by 1 spaces
 2: 22,
 3: 33}
{ 1: 11,    #Indent = 2 Each entry is indented by 2 spaces
  2: 22,
  3: 33}

如您所见,问题仍然在于:“{
如果那不存在,那么缩进将是均匀的。函数 pformat() 被编码为针对该字符进行调整。

Logic's answer has you covered as to why you are having the indentation issue. As (IMO) a more concise approach however, you can make use of json。此输出假设 elements 是指字典元素:

import json
obj_name = 'MY_DCT = '
obj_body_as_dct = {1: 11, 2: 22, 3: 33}

stringy = "\"\"\"" + obj_name + "{" \
          + str(json.dumps(obj_body_as_dct, indent=4, separators=(',', ': ')))[1:] + "\"\"\""
print(stringy)

输出:

"""MY_DCT = {
    "1": 11,
    "2": 22,
    "3": 33
}"""

indentpformat 中的默认值是 1,因此按键会一个接一个地出现。

例如,pformat(d, indent=0, width=1) 将导致此字符串:

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

indent=1:

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

indent=2

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

总是在第一行少一个空格。


由于目标是在第一行之后显示 dict 元素,并且所有元素都缩进 4 个空格,因此在第一个元素之前添加一个空格并使用 indent=4 将适用于某些字典(如建议的那样通过@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}

最吸引人的解决方案(对于我正在处理的数据)是保留 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)

产生这个字符串:

MY_DCT = {
    1: {'a': 'aa',
        'b': [1,
              2,
              3]},
    2: 22,
    3: 33}