Подтвердить что ты не робот

Многострочная строка с аргументами. Как объявить?

Скажем, у меня очень длинная строка с аргументами, которые я хочу создать. Я знаю, вы можете создать многострочную строку с

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

Но теперь скажем, что я хочу передать 1, 2 и 3 в качестве аргументов.

Это работает

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

Но если у меня есть супер длинная строка с 30 + аргументами, как я могу передать эти аргументы в нескольких строках? Передача их в одной строке поражает цель даже попытки создания многострочной строки.

Спасибо всем за помощь и понимание.

4b9b3361

Ответ 1

Вы можете злоупотреблять свойствами продолжения строки в скобках ( и запятой ,.

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

Ответ 2

Вы можете использовать функцию str.format(), которая разрешает именованные аргументы, поэтому:

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

Конечно, вы можете расширить это, используя синтаксис Python *args чтобы вы могли передать tuple или list:

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() найти здесь.

Ответ 3

Еще один вариант с функцией string.format() - Function.

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

Ответ 4

Самым простым способом может быть использование интерполяции литеральных строк (доступно начиная с Python 3.6 и далее при условии, что все аргументы находятся в области видимости).

cmd = f"""line {1}
      line {2}
      line {3}"""

Ответ 5

Чтобы аргументы в одной строке были вставлены, вы можете сделать это следующим образом:

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

[EDIT:] В ответ на первый комментарий я придумал следующее:

cmd = "\n".join([
      "line %d"%1,
      "line %d"%2,
      "line %d"%3])

Ответ 6

Это работает для меня:

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

Ответ 7

Как говорит @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

Обновление от 21 мая 2019 года. Иногда "уродливая" многострочная строка - действительно лучший путь!

Итак, я использую Python для автоматической генерации заголовочных и исходных файлов (.h/.c) C из текстовых файлов конфигурации -based, и после того, как я это сделал, я пришел к выводу, что преимущества простого копирования - вставка больших кусков текста из файла конфигурации в мой скрипт на Python перевешивает любые "уродливые" факторы.

Поэтому я определил, что следующий вариант - мой предпочтительный способ сделать это, когда требуется, например, большая многострочная скопированная строка:

Опция 1:
- Используйте круглые скобки вокруг всей длинной строки, чтобы открывающее """ находилось на новой строке

# Get some levels of indentation to still show the "ugliness" effect.
if (True):
    if (True):
        if (True):
            header = (
"""
/*
my custom file header info here
*/

#pragma once

#include "{}"

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

            print("header =" + header)

Вариант 2:
- Без скобок, но все равно ставьте закрывающую """ на отдельной строке

# Get some levels of indentation to still show the "ugliness" effect.
if (True):
    if (True):
        if (True):
            header = """
/*
my custom file header info here
*/

#pragma once

#include "{}"

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

            print("header =" + header)

Вариант 3:
- Не ставьте круглые скобки вокруг всей строки и ставьте закрывающую """ на той же строке, что и содержимое строки, чтобы предотвратить добавление (потенциально нежелательного) \n в конце.
- Однако оставьте остаток format( на новой строке (или на многих новых строках), если он длинный.

# Get some levels of indentation to still show the "ugliness" effect.
if (True):
    if (True):
        if (True):
            header = """
/*
my custom file header info here
*/

#pragma once

#include "{}"

const {} {};""".format(
    include, struct_t, struct) # indentation here can literally be *anything*, but I like to indent 1 level; since it inside parenthesis, however, it doesn't matter

            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;


Собираю все вместе: смесь из "красивой" и "некрасивой" методы вместе, чтобы получить лучший результат в этом демо печати строки документации документации для модуля!

Здесь приведен базовый пример использования как "симпатичных", так и "некрасивых" многострочных строковых методов, представленных выше, чтобы получить максимальную выгоду от каждого из них. Здесь также показано, как использовать и печатать "строки документации" для документирования вашего модуля. Обратите внимание, что многострочный метод """ -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() 

Выход:
- Обратите внимание, насколько красиво и хорошо отформатировано все это автоматически, так как вкладки, новые строки и интервал между строками документов автоматически сохраняются при их печати таким образом!


########################  
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 docstring 
      

Ответ 8

Вот самая простая версия, которая также совместима с IDE с точки зрения проверки аргументов format:

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

Ответ 9

Вы можете использовать textwrap.dedent для удаления 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