带参数的多行字符串.怎么申报?

Qui*_*ion 54 python

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

cmd = """line 1
      line 2
      line 3"""
Run Code Online (Sandbox Code Playgroud)

但现在让我说我想传递1,2和3作为参数.

这有效

cmd = """line %d
      line %d
      line %d""" % (1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

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

感谢任何人提前获得他们的帮助和见解.

Chi*_*chi 75

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

'''line {0}
line {1}
line {2}'''.format(1,2,3)
Run Code Online (Sandbox Code Playgroud)

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

args = (1,2,3)
'''line {0}
line {1}
line {2}'''.format(*args)
Run Code Online (Sandbox Code Playgroud)

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

args = {'arg1':1, 'arg2':2, 'arg3':3}
'''line {arg1}
line {arg2}
line {arg3}'''.format(**args)
Run Code Online (Sandbox Code Playgroud)

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

  • 如果字符串中有大括号,请使用双大括号将其转义:{{ 和 }} (2认同)

Fré*_*idi 39

您可以滥用括号(和逗号的行继续属性,.

cmd = """line %d
      line %d
      line %d""" % (
      1,
      2,
      3)
Run Code Online (Sandbox Code Playgroud)


eli*_*lim 12

使用string.format() - Function的另一个变体.

s = "{0} " \
    "{1} " \
    "{2}" \
    .format("Hello", "world", "from a multiline string")    
print(s)
Run Code Online (Sandbox Code Playgroud)


Mic*_*rer 11

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

cmd = f"""line {1}
      line {2}
      line {3}"""
Run Code Online (Sandbox Code Playgroud)

  • 为什么这不是最好的方法?它更具可读性并且更容易编写。 (2认同)

Gab*_*les 7

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'
Run Code Online (Sandbox Code Playgroud)

对于所有示例

import textwrap
Run Code Online (Sandbox Code Playgroud)

示例 1

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

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

print(cmd)
Run Code Online (Sandbox Code Playgroud)

这样做(并保持漂亮,干净,缩进)!

import textwrap

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

print(cmd)
Run Code Online (Sandbox Code Playgroud)

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

import textwrap

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

print(cmd)
Run Code Online (Sandbox Code Playgroud)

示例 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)
Run Code Online (Sandbox Code Playgroud)

当然,如果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)
Run Code Online (Sandbox Code Playgroud)

示例 3

不是 this正如我在我的原始答案中所述(它保持了漂亮的缩进,但使用起来有点乏味):

print("\n\n" + 
      "########################\n" + 
      "PRINT DOCSTRING DEMO:\n" + 
      "########################")
Run Code Online (Sandbox Code Playgroud)

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

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

      ########################
      PRINT DOCSTRING DEMO:
      ########################\
      """))
Run Code Online (Sandbox Code Playgroud)

示例 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__))
Run Code Online (Sandbox Code Playgroud)

...这样做,它用于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__))
Run Code Online (Sandbox Code Playgroud)

运行上面的代码

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

运行命令:

./textwrap_practice_1.py
Run Code Online (Sandbox Code Playgroud)

或者:

python3 textwrap_practice_1.py
Run Code Online (Sandbox Code Playgroud)


小智 5

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

cmd = "line %d\n"%1 +\
      "line %d\n"%2 +\
      "line %d\n"%3
Run Code Online (Sandbox Code Playgroud)

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

cmd = "\n".join([
      "line %d"%1,
      "line %d"%2,
      "line %d"%3])
Run Code Online (Sandbox Code Playgroud)


Gab*_*les 5

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


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

'''line {0}
line {1}
line {2}'''.format(1,2,3)
Run Code Online (Sandbox Code Playgroud)

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

'''line {0}
   line {1}
   line {2}'''.format(1,2,3)
Run Code Online (Sandbox Code Playgroud)

那行得通,但这是错误的!它可将所有空格左边的line {1}line {2}作为真正的空间,所以在印刷它看起来愚蠢的:

1
   2
   3
Run Code Online (Sandbox Code Playgroud)

代替

1
2
3
Run Code Online (Sandbox Code Playgroud)

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

('line {0}\n' + 
 'line {1}\n' +
 'line {2}').format(1,2,3)
Run Code Online (Sandbox Code Playgroud)

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

完整示例:

丑陋的源代码!

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
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

输出:

num1 = 7
num2 = 100
num3 = 75.49

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

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

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

选项1:

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

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

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

    #pragma once

    #包括 ”{}”

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

              print("header =" + header)
    
    Run Code Online (Sandbox Code Playgroud)

选项 2:

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

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

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

    #pragma once

    #包括 ”{}”

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

              print("header =" + header)
    
    Run Code Online (Sandbox Code Playgroud)

选项 3:

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

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

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

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

    #pragma once

    #包括 ”{}”

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

              print("header =" + header)
    
    Run Code Online (Sandbox Code Playgroud)

输出:

  • 选项 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;

Run Code Online (Sandbox Code Playgroud)

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

下面是一个基本示例,它同时使用了上面介绍的“漂亮”和“丑陋”多行字符串方法,以便获得每种方法的最大好处。这也展示了如何使用和打印模块“docstrings”来记录你的模块。请注意"""基于 -based 的多行技术如何为我们提供很大的间距,因为我在下面所做的方式\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() 
Run Code Online (Sandbox Code Playgroud)

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

  
########################  
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  
          
  
Run Code Online (Sandbox Code Playgroud)

参考:

  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 
    
    Run Code Online (Sandbox Code Playgroud)