python中的多行字符串格式

时间:2017-12-08 10:00:52

标签: python multiline

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

*********************************************************************
                                 hello
********************************************************************* 

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

$ cat varibale.py 
decorator = """ **********************************************************************
                               {}
            ********************************************************************** """
print(decorator.format("hello"))

输出:

**********************************************************************
                               hello
            **********************************************************************

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

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

$ cat varibale.py 
decorator = """ **********************************************************************
                             {}
********************************************************************* 
"""
print(decorator.format("hello"))

输出:

 **********************************************************************
                             hello
********************************************************************* 

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

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

4 个答案:

答案 0 :(得分:7)

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

s = '''\
*********************************************************************
                                 hello
*********************************************************************
'''
print(s)

<强>输出

*********************************************************************
                                 hello
*********************************************************************

然而,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))

<强>输出

*********************************************************************
                                hello
*********************************************************************
****************
  Hello, world
****************

如何运作

那格式字符串有点密集,所以我想我应该尝试解释一下。 ;)有关此主题的完整信息,请参阅文档中的Format String Syntax。下面的解释借鉴了&amp;解释那些文档。

'{0}\n{1:>{2}}\n{0}'.format(stars, s, pad)

格式字符串中{}中包含的内容称为“替换字段”。替换字段中的第一项是可选字段名称。这使我们可以识别.format的哪个arg与此替换字段一起使用。字段名称有几种可能的变体,此格式字符串使用数字名称,因此它按位置标识.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放在这里(s),右对齐在一个由arg 2(pad)给出的宽度的字段中。只允许一个级别的替换字段嵌套,但很难想到您实际需要更深层嵌套的情况。

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

我希望这有足够的意义。 :)

在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}'

答案 1 :(得分:6)

你可以举例如:

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

或者如果你想让文字宽度动态:

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

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

fn('hello')
如果需要写入文件,请使用

或稍微通用的版本:

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

答案 2 :(得分:0)

也许:

print '*' * 80 + '\n' + ' ' * 38 + 'hello' + '\n' + '*' *80

OR 如果是python3

a = lambda x,c,mess: print(c*x + ('\n' if not mess else mess))
a(80, '*', None)
a(38, ' ', 'Hello')
a(80, '*', None)

答案 3 :(得分:0)

另一种方法是使用textwrap模块

import textwrap

decorator = """\
            ****
            {0}
            ****"""

print(textwrap.dedent(decorator.format("hello")))