python中的多行字符串格式

Her*_*arn 7 python multiline

首先,我正在努力获得如下所需的输出:

*********************************************************************
                                 hello
********************************************************************* 
Run Code Online (Sandbox Code Playgroud)

为实现这一点,我已将所需的输出分配给具有多行字符串的变量,并使用格式打印相同的变量.

$ cat varibale.py 
decorator = """ **********************************************************************
                               {}
            ********************************************************************** """
print(decorator.format("hello"))
Run Code Online (Sandbox Code Playgroud)

输出:

**********************************************************************
                               hello
            **********************************************************************
Run Code Online (Sandbox Code Playgroud)

上述方法的问题是第三行输出中额外空格看起来很奇怪.

我能够通过以下方式实现这一目标:

$ cat varibale.py 
decorator = """ **********************************************************************
                             {}
********************************************************************* 
"""
print(decorator.format("hello"))
Run Code Online (Sandbox Code Playgroud)

输出:

 **********************************************************************
                             hello
********************************************************************* 
Run Code Online (Sandbox Code Playgroud)

但是这样我的代码看起来不太好,因为它没有跟随缩进.

请建议正确的方法来实现所需的输出.

ewc*_*wcz 7

你可以举例如下:

print('*'*80)
print('{msg:^80s}'.format(msg = 'HELLO')) #^ centers the message
print('*'*80)
Run Code Online (Sandbox Code Playgroud)

或者如果你想要文本宽度动态:

def fn(msg, w = 80):
    delim = '*'*w
    fmt = '{msg:^%ds}'%w

    print(delim)
    print(fmt.format(msg=msg))
    print(delim)

fn('hello')
Run Code Online (Sandbox Code Playgroud)

或者稍微通用的版本,如果您需要写入文件:

import sys

def fn(msg, w = 80, F = sys.stdout):
    delim = '*'*w
    fmt = '{delim:s}\n{msg:^%ds}\n{delim:s}\n'%w
    F.write(fmt.format(delim = delim, msg = msg))

fn('hello')
Run Code Online (Sandbox Code Playgroud)


PM *_*ing 7

使多行文字字符串看起来很好的一种方法是使用反斜杠来转义换行符,如下所示:

s = '''\
*********************************************************************
                                 hello
*********************************************************************
'''
print(s)
Run Code Online (Sandbox Code Playgroud)

产量

*********************************************************************
                                 hello
*********************************************************************
Run Code Online (Sandbox Code Playgroud)

但是,PEP-008不鼓励这样的反斜杠使用.它太脆弱了:如果反斜杠和换行符之间有空格,那么换行符就不会被转义,反斜杠也会打印出来.

更通用的方法是使用一个函数来计算文本居中所需的填充量,并通过嵌套格式说明符应用它.例如:

def banner(s, width=69):
    stars = '*' * width
    pad = (width + len(s)) // 2
    return '{0}\n{1:>{2}}\n{0}'.format(stars, s, pad)

print(banner('hello'))
print(banner('Hello, world', width=16))
Run Code Online (Sandbox Code Playgroud)

产量

*********************************************************************
                                hello
*********************************************************************
****************
  Hello, world
****************
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

那格式字符串有点密集,所以我想我应该尝试解释它.;)有关此主题的完整信息,请参阅文档中的格式字符串语法.下面的解释借鉴了这些文档并解释了这些文档.

'{0}\n{1:>{2}}\n{0}'.format(stars, s, pad)
Run Code Online (Sandbox Code Playgroud)

包含在{}格式字符串中的内容称为"替换字段".替换字段中的第一项是可选字段名称.这让我们可以确定哪个arg .format与此替换字段一起使用.字段名称有几种可能的变体,此格式字符串使用数字名称,因此它.format按位置标识args.即,0对应stars,1对应s,2对应pad.

如果没有给出字段名称,它们将自动填入数字0,1,2,...等等(除非您使用的是Python 2.6,其中字段名称是必需的).这在大多数情况下非常有用,因此大多数格式字符串都不会使用字段名称.

在字段名称之后,我们可以给出"格式说明符"或"格式规范",其描述了如何呈现该值.冒号:将字段名称与格式规范分开.如果您不提供格式规范,那么您将获得默认格式,并且大部分时间都足够.但在这里我们确实需要更多控制,因此我们需要提供格式规范.

在表单规范中,>符号强制字段在可用空间内右对齐.在对齐符号之后,我们可以提供一个数字来指定最小字段宽度; 如有必要,该字段将自动变大.

例如,'{0:>6}'.format('test')说将参数0('test')放在一个至少6个字符宽的空间中,与右边对齐.这导致了字符串' test'.

但格式规范实际上可以包含一个全新的替换字段!这允许我们提供变量来控制字段宽度.所以在我的格式字符串中{1:>{2}}说arg 1 here(s),右对齐在一个由arg 2(pad)给出的宽度的字段中.只允许一个级别的替换字段嵌套,但很难想象您实际上需要更深层次嵌套的情况.

所以把它们放在一起:'{0}\n{1:>{2}}\n{0}'告诉.format构建一个以arg 0(stars)开头的字符串,使用默认的格式规范,然后是换行符,接着是arg 1(s)在宽度字段中右对齐pad,然后是另一个换行符,最后是stars再次通过arg 0().

我希望这足够了.:)


在Python 3.6+中,我们可以使用f-string:

def banner(s, width=69):
    stars = '*' * width
    pad = (width + len(s)) // 2
    return f'{stars}\n{s:>{pad}}\n{stars}'
Run Code Online (Sandbox Code Playgroud)