88

假设我有一个非常长的字符串,其中包含要创建的参数。我知道你可以创建一个多行字符串

cmd = """line 1
      line 2
      line 3"""

但现在假设我想传递 1、2 和 3 作为参数。

这有效

cmd = """line %d
      line %d
      line %d""" % (1, 2, 3)

但是,如果我有一个包含 30 多个参数的超长字符串,我怎么可能在多行中传递这些参数?在单行中传递它们甚至破坏了尝试创建多行字符串的目的。

提前感谢任何人的帮助和洞察力。

4

10 回答 10

105

您可以使用str.format()允许命名参数的函数,因此:

'''line {0}
line {1}
line {2}'''.format(1,2,3)

您当然可以使用 Python 的*args语法扩展它以允许您传入 atuplelist

args = (1,2,3)
'''line {0}
line {1}
line {2}'''.format(*args)

如果您可以智能地命名您的参数,那么最强大的解决方案(尽管是最密集的一种)将是使用 Python 的**kwargs语法来传递字典:

args = {'arg1':1, 'arg2':2, 'arg3':3}
'''line {arg1}
line {arg2}
line {arg3}'''.format(**args)

有关str.format()迷你语言的更多信息,请访问此处

于 2012-06-11T19:22:13.770 回答
55

您可能会滥用括号(和逗号的行延续属性,

cmd = """line %d
      line %d
      line %d""" % (
      1,
      2,
      3)
于 2012-06-11T18:34:28.093 回答
31

最简单的方法可能是使用文字字符串插值(从 Python 3.6 开始可用,并假设所有参数都在范围内)。

cmd = f"""line {1}
      line {2}
      line {3}"""
于 2017-08-23T10:48:47.997 回答
17

string.format()-Function 的另一种变体。

s = "{0} " \
    "{1} " \
    "{2}" \
    .format("Hello", "world", "from a multiline string")    
print(s)
于 2017-08-23T08:31:22.900 回答
11

TLDR;

直接跳下来看看下面的示例 1 和示例 4。

完整答案:

上周(2020 年 10 月)我刚刚才了解Pythontextwrap模块textwrap.dedent(),它具有非常方便的功能,考虑到它自 Python 2.7 以来就已经存在,我不敢相信它没有更受欢迎!

使用textwrap.dedent()多行字符串解决了我之前回答的所有问题!

这是它的官方文档(强调添加):

textwrap.dedent(text)

从文本的每一行中删除任何常见的前导空格。

这可用于使三引号字符串与显示的左边缘对齐,同时仍以缩进形式在源代码中显示它们。

请注意,制表符和空格都被视为空格,但它们不相等:行" hello""\thello"被认为没有共同的前导空格。

仅包含空格的行在输入中被忽略,并在输出中标准化为单个换行符。

例如:

def test():
    # end first line with \ to avoid the empty line!
    s = '''\
    hello
      world
    '''
    print(repr(s))          # prints '    hello\n      world\n    '
    print(repr(dedent(s)))  # prints 'hello\n  world\n'

对于所有示例

import textwrap

示例 1

因此,而不是 this,正如最受支持的答案所述(这失去了漂亮、干净、缩进):

cmd = '''line {0}
line {1}
line {2}'''.format(1,2,3)

print(cmd)

这样做(并保持漂亮、干净、压痕)!

import textwrap

cmd = textwrap.dedent('''\
    line {0}
    line {1}
    line {2}''').format(1,2,3)

print(cmd)

或者,使用 Python3 的新改进的“f”格式字符串而不是.format()方法!:

import textwrap

var0 = 1
var1 = 2
var2 = 3
cmd = textwrap.dedent(f'''\
    line {var0}
    line {var1}
    line {var2}''')

print(cmd)

示例 2

如果format()函数有很多参数,可以根据需要将它们放在多行上。请注意,format()参数在这里占据了两行:

cmd = textwrap.dedent('''\
    line {0}
    line {1}
    line {2}
    line {3}
    line {4}
    line {5}
    line {6}
    line {7}
    line {8}
    line {9}
    line {10}
    line {11}
    line {12}
    line {13}
    line {14}
    line {15}
    line {16}
    line {17}
    line {18}
    line {19}''').format(
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
        11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    )

print(cmd)

当然,如果format()参数真的很长,您也可以将每个参数单独放在一行:

cmd = textwrap.dedent('''\
    line {0}
    line {1}
    line {2}
    line {3}
    line {4}
    line {5}
    line {6}
    line {7}
    line {8}
    line {9}
    line {10}
    line {11}
    line {12}
    line {13}
    line {14}
    line {15}
    line {16}
    line {17}
    line {18}
    line {19}''').format(
        100000000000000000000000000000000000000000000000000000000000000000001,
        100000000000000000000000000000000000000000000000000000000000000000002,
        100000000000000000000000000000000000000000000000000000000000000000003,
        100000000000000000000000000000000000000000000000000000000000000000004,
        100000000000000000000000000000000000000000000000000000000000000000005,
        100000000000000000000000000000000000000000000000000000000000000000006,
        100000000000000000000000000000000000000000000000000000000000000000007,
        100000000000000000000000000000000000000000000000000000000000000000008,
        100000000000000000000000000000000000000000000000000000000000000000009,
        100000000000000000000000000000000000000000000000000000000000000000010,
        100000000000000000000000000000000000000000000000000000000000000000011,
        100000000000000000000000000000000000000000000000000000000000000000012,
        100000000000000000000000000000000000000000000000000000000000000000013,
        100000000000000000000000000000000000000000000000000000000000000000014,
        100000000000000000000000000000000000000000000000000000000000000000015,
        100000000000000000000000000000000000000000000000000000000000000000016,
        100000000000000000000000000000000000000000000000000000000000000000017,
        100000000000000000000000000000000000000000000000000000000000000000018,
        100000000000000000000000000000000000000000000000000000000000000000019,
        100000000000000000000000000000000000000000000000000000000000000000020,
    )

print(cmd)

示例 3

不是 this正如我在原始答案中所说的那样(缩进看起来很漂亮,但使用起来有点乏味):

print("\n\n" + 
      "########################\n" + 
      "PRINT DOCSTRING DEMO:\n" + 
      "########################")

...你现在可以做到这一点!--这允许我的多行字符串在打印时“与显示器的左边缘对齐,同时仍以缩进形式在源代码中显示它们”(参见官方文档):

# Note: use the `\` below to prevent the implicit newline right after it from being printed.
print(textwrap.dedent("""

      ########################
      PRINT DOCSTRING DEMO:
      ########################\
      """))

示例 4

不是 this,它的中间有一些难看的缺乏缩进:

def printDocstrings1():
    """
    Print all document strings for this module, then exit.
    Params:  NA
    Returns: NA
    """

    # A LITTLE BIT UGLY, BUT IT WORKS.
    print("""
---------------------
Module Documentation:
---------------------
printDocstrings:{}
myFunc1:{}
class Math:{}
    __init__:{}
    add:{}
    subtract:{}""".format(
        printDocstrings1.__doc__,
        myFunc1.__doc__,
        Math.__doc__,
        Math.__init__.__doc__,
        Math.add.__doc__,
        Math.subtract.__doc__))

...这样做,用于textwrap.dedent()始终保持美观的缩进!:

def printDocstrings2():
    """
    Print all document strings for this module, then exit.
    Params:  NA
    Returns: NA
    """

    # MUCH CLEANER! Now I can have the proper indentation on the left withOUT
    # it printing that indentation!
    print(textwrap.dedent("""\
    ---------------------
    Module Documentation:
    ---------------------
    printDocstrings:{}
    myFunc1:{}
    class Math:{}
        __init__:{}
        add:{}
        subtract:{}""").format(
            printDocstrings2.__doc__,
            myFunc1.__doc__,
            Math.__doc__,
            Math.__init__.__doc__,
            Math.add.__doc__,
            Math.subtract.__doc__))

运行上面的代码

您可以在我的eRCaGuy_hello_world GitHub存储库中运行我上面的测试代码: textwrap_practice_1.py

运行命令:

./textwrap_practice_1.py

或者:

python3 textwrap_practice_1.py
于 2020-10-20T01:34:54.753 回答
5

2020 年 10 月 19 日更新:尽管我在这里的回答仍然很有见地、内容丰富且值得一读,但我现在在这里有了一个更好的答案,它依赖于真正有用的textwrap.dedent()功能。


正如@Chinmay Kanchi 所说,您可以这样做:

'''line {0}
line {1}
line {2}'''.format(1,2,3)

但是,我认为它看起来很傻,必须在新行上完全左对齐,特别是当你这样做时已经缩进了几个级别,所以我希望它更像这样写:

'''line {0}
   line {1}
   line {2}'''.format(1,2,3)

那行得通,但是错了!它将左侧的所有空格都解释line {1}line {2}真实空格,因此打印它会看起来很傻:

1
   2
   3

代替

1
2
3

因此,一种解决方法是使用+运算符进行连接,并在连接的字符串周围加上括号,以及显式的换行符 ( \n) 字符,如下所示:

('line {0}\n' + 
 'line {1}\n' +
 'line {2}').format(1,2,3)

完美(在我看来)!现在,如果您打印它,它在源代码和实际字符串中看起来都很好并且对齐。

完整示例:

丑陋的源代码!

num1 = 7
num2 = 100
num3 = 75.49

# Get some levels of indentation to really show the effect well.
# THIS IS *UGLY*! Notice the weird forced-left-align thing for the string I want to print!
if (True):
    if (True):
        if (True):
            # AAAAAH! This is hard to look at!
            print('''num1 = {}
num2 = {}
num3 = {}'''.format(num1, num2, num3))

            # More lines of code go here
            # etc
            # etc

输出:

num1 = 7
num2 = 100
num3 = 75.49

漂亮的例子!啊,很高兴在源代码中看到。:)

这是我更喜欢的。

# Get some levels of indentation to really show the effect well.
if (True):
    if (True):
        if (True):
            # IMPORTANT: the extra set of parenthesis to tie all of the concatenated strings together here is *required*!
            print(('num1 = {}\n' + 
                   'num2 = {}\n' + 
                   'num3 = {}')
                   .format(num1, num2, num3))

            # More lines of code go here
            # etc
            # etc

输出:

num1 = 7
num2 = 100
num3 = 75.49

2019 年 5 月 21 日更新:有时“丑陋”的多行字符串确实是最好的方法!

所以,我一直在使用 Python从基于文本的配置文件中自动生成 C 头文件和源文件(.h/.c),在做了相当多的工作之后,我得出结论,简单地复制的好处——将配置文件中的大量文本粘贴到我的 Python 脚本中比任何“丑陋”因素更重要。

因此,我确定以下是我在需要大的多行复制粘贴字符串时首选的方法,例如:

选项1:

  • 在整个长字符串周围使用括号以允许开头"""在新行上

    获得一定程度的缩进仍然显示“丑陋”效果。

    if (True): if (True): if (True): header = ( """ /* 我的自定义文件头信息在这里 */

    #pragma 一次

    #包括 ”{}”

    常量 {} {}; """).format(include, struct_t, struct)

              print("header =" + header)
    

选项 2:

  • 没有括号,但仍然把结尾"""放在自己的行上

    获得一定程度的缩进仍然显示“丑陋”效果。

    if (True): if (True): if (True): header = """ /* 我的自定义文件头信息在这里 */

    #pragma 一次

    #包括 ”{}”

    常量 {} {}; """.format(包括,struct_t,结构)

              print("header =" + header)
    

选项 3:

  • 整个字符串周围没有括号,并将结尾"""与字符串内容放在同一行,以防止\n在末尾添加(可能不受欢迎)。

  • 但是,如果它很长,请将其余部分format(放在一个新行(或许多新行)上。

    获得一定程度的缩进仍然显示“丑陋”效果。

    if (True): if (True): if (True): header = """ /* 我的自定义文件头信息在这里 */

    #pragma 一次

    #包括 ”{}”

    const {} {};""".format(include, struct_t, struct) # 这里的缩进实际上可以是任何东西,但我喜欢缩进 1 级;但是因为它在括号内,所以没关系

              print("header =" + header)
    

输出:

  • 选项 1 和 2 产生完全相同的输出,\n在字符串的最后有一个额外的输出,这在大多数情况下是可以的
  • 选项 3 产生与选项 1 和 2 相同的确切输出,只是它在字符串的最后没有额外\n的,以防您的情况不希望这样做
  • 无论您使用选项 1、2 还是 3 都无关紧要——此时这只是用户偏好,除了\n上面提到的额外选项

这是上面选项 1、2 和 3 打印的内容:

/*
my custom file header info here
*/

#pragma once

#include "<stdint.h>"

const my_struct_t my_struct;


把它放在一起:将“漂亮”和“丑陋”的方法混合在一起,以在这个为您的模块打印文档字符串文档的演示中获得最佳结果!

这是一个使用上面介绍的“漂亮”和“丑陋”多行字符串方法的基本示例,以便获得每个方法的最大好处。这也展示了如何使用和打印模块“文档字符串”来记录你的模块。请注意"""基于 - 的多行技术如何为我们提供了很大的间距,因为我在下面所做的方式是在开始之后和结束之前自动换行 ( \n),因为这就是字符串的编写方式。""""""

# PRETTY, AND GOOD.
print("\n\n" + 
      "########################\n" + 
      "PRINT DOCSTRING DEMO:\n" + 
      "########################")

import sys

def printDocstrings():
    """
    Print all document strings for this module, then exit.
    Params:  NA
    Returns: NA
    """

    # A LITTLE BIT UGLY, BUT GOOD! THIS WORKS GREAT HERE!
    print("""
---------------------
Module Documentation:
---------------------
printDocstrings:{}
myFunc1:{}
class Math:{}
    __init__:{}
    add:{}
    subtract:{}""".format(
        printDocstrings.__doc__,
        myFunc1.__doc__,
        Math.__doc__,
        Math.__init__.__doc__,
        Math.add.__doc__,
        Math.subtract.__doc__))

    sys.exit()

def myFunc1():
    """
    Do something.
    Params:  NA
    Returns: NA
    """
    pass

class Math:
    """
    A basic "math" class to add and subtract
    """

    def __init__(self):
        """
        New object initialization function.
        Params:  NA
        Returns: NA
        """
        pass

    def add(a, b):
        """
        Add a and b together.
        Params:  a   1st number to add
                 b   2nd number to add
        Returns: the sum of a + b
        """
        return a + b

    def subtract(a, b):
        """
        Subtract b from a.
        Params:  a   number to subtract from
                 b   number to subtract
        Returns: the result of a - b
        """
        return a - b

printDocstrings() 

输出:
- 注意它的自动格式是多么漂亮和良好,因为当您以这种方式打印它们时,文档字符串的制表符、换行符和间距都会自动保留!

  
########################  
PRINT DOCSTRING DEMO:  
########################  
  
---------------------  
Module Documentation:  
---------------------  
printDocstrings:  
    Print all document strings for this module, then exit.  
    Params:  NA  
    Returns: NA  
      
myFunc1:  
    Do something.  
    Params:  NA  
    Returns: NA  
      
class Math:  
    A basic "math" class to add and subtract  
      
    __init__:  
        New object initialization function.  
        Params:  NA  
        Returns: NA  
          
    add:  
        Add a and b together.  
        Params:  a   1st number to add  
                 b   2nd number to add  
        Returns: the sum of a + b  
          
    subtract:  
        Subtract b from a.  
        Params:  a   number to subtract from  
                 b   number to subtract  
        Returns: the result of a - b  
          
  

参考:

  1. Python 文档字符串:https ://www.geeksforgeeks.org/python-docstrings/
  • 注意:您也可以使用该help()方法访问模块或类的文档(但以交互方式),如上面的链接所示,如下所示:

         help(Math)  # to interactively display Class docstring
         help(Math.add)  # to interactively display method's docstring 
    
于 2019-02-07T01:08:11.777 回答
4

要将参数插入到同一行中,您可以这样做:

cmd = "line %d\n"%1 +\
      "line %d\n"%2 +\
      "line %d\n"%3

[编辑:] 在回复第一条评论时,我想出了这个:

cmd = "\n".join([
      "line %d"%1,
      "line %d"%2,
      "line %d"%3])
于 2012-06-11T18:38:39.247 回答
3

您可以使用textwrap.dedent从行中删除前导空格:

import textwrap

cmd = str.strip(textwrap.dedent(
    '''
        line {}
            line with indent
        line {}
        line {}
    '''
    .format(1, 2, 3)))

这导致:

line 1
    line with indent
line 2
line 3
于 2019-03-15T15:55:22.740 回答
2

这对我有用:

cmd = """line %d
      line %d
      line %d""" % (
          1,
          2,
          3
      )
于 2012-06-11T18:34:41.697 回答
1

format这是最简单的版本,它在检查参数方面也是 IDE 友好的:

cmd = (
    'line {}\n'
    'line {}\n'
    'line {}\n'
    .format(1, 2, 3))

多行参数版本:

cmd = (
    'line {}\n'
    'line {}\n'
    'line {}\n'
    .format(
        'very very very very very very very very very long 1',
        'very very very very very very very very very long 2',
        'very very very very very very very very very long 3',
    )
)
于 2019-03-15T15:50:25.970 回答