Jak utworzyć wielowierszowy ciąg znaków w języku Python ze zmiennymi wbudowanymi?

102

Szukam czystego sposobu używania zmiennych w wielowierszowym ciągu Pythona. Powiedzmy, że chcę wykonać następujące czynności:

string1 = go
string2 = now
string3 = great

"""
I will $string1 there
I will go $string2
$string3
"""

Szukam, aby sprawdzić, czy jest coś podobnego do $w Perlu, aby wskazać zmienną w składni Pythona.

Jeśli nie - jaki jest najczystszy sposób na utworzenie łańcucha wielowierszowego ze zmiennymi?

ewolucja
źródło

Odpowiedzi:

158

Powszechnym sposobem jest format()funkcja:

>>> s = "This is an {example} with {vars}".format(vars="variables", example="example")
>>> s
'This is an example with variables'

Działa dobrze z wieloliniowym ciągiem formatu:

>>> s = '''\
... This is a {length} example.
... Here is a {ordinal} line.\
... '''.format(length='multi-line', ordinal='second')
>>> print(s)
This is a multi-line example.
Here is a second line.

Możesz również przekazać słownik ze zmiennymi:

>>> d = { 'vars': "variables", 'example': "example" }
>>> s = "This is an {example} with {vars}"
>>> s.format(**d)
'This is an example with variables'

Najbliższą rzeczą, o którą prosiłeś (pod względem składni), są ciągi szablonów . Na przykład:

>>> from string import Template
>>> t = Template("This is an $example with $vars")
>>> t.substitute({ 'example': "example", 'vars': "variables"})
'This is an example with variables'

Powinienem jednak dodać, że format()funkcja jest bardziej powszechna, ponieważ jest łatwo dostępna i nie wymaga linii importu.

Simeon Visser
źródło
2
Mógłby użyć vars()lub locals()jako słownika, o którym mowa
Ismail Badawi
2
@isbadawi Jawne jest lepsze niż niejawne. Lepiej jest przekazywać tylko potrzebne zmienne. Jeśli nie wiesz, czego potrzebujesz, ponieważ ciąg jest dostarczany przez użytkownika, „zmiennymi” powinny być i dicttak elementy.
agf
Drugim rozwiązaniem jest najczystsza IMO. Słownik wraz z wyraźną nazwą zmiennej ze słownika w żądaniu wielowierszowym. Będę używać tej metody. Dzięki. Mnóstwo świetnych odpowiedzi poniżej, ale to było idealne.
ewolucja
@SimeonVisser, "string" .format (...) nie jest prawidłowy w starszych wersjach Pythona (np. 2.4)
Oz123
Jeśli używasz nawiasów klamrowych, musisz uciec jak {{this}}.
Jonny
54

UWAGA : Zalecanym sposobem formatowania ciągów w Pythonie jest użycie format(), jak opisano w zaakceptowanej odpowiedzi . Zachowuję tę odpowiedź jako przykład obsługiwanej składni w stylu C.

# NOTE: format() is a better choice!
string1 = "go"
string2 = "now"
string3 = "great"

s = """
I will %s there
I will go %s
%s
""" % (string1, string2, string3)

print(s)

Trochę czytania:

David Cain
źródło
2
To nie jest to samo, ponieważ OP chce nazwanych parametrów, a nie pozycyjnych.
Ismail Badawi
2
To wciąż dobre rozwiązanie, a dla interpolacji wieloliniowej jest bardziej bezpośrednie. Nie musisz niczego importować i używa zwykłej interpolacji w Pythonie.
unflores
4
Prawdopodobnie mogłeś odpowiedzieć na to pytanie, trochę googlując ” Oznacza to, że nie znaleźliśmy tego posta po Googlingu ...
Stevoisiak
32

Możesz użyć f-stringów Pythona 3.6 dla zmiennych wewnątrz wieloliniowych lub długich jednowierszowych łańcuchów. Możesz ręcznie określić znaki nowego wiersza za pomocą \n.

Zmienne w ciągu wieloliniowym

string1 = "go"
string2 = "now"
string3 = "great"

multiline_string = (f"I will {string1} there\n"
                    f"I will go {string2}.\n"
                    f"{string3}.")

print(multiline_string)

Pójdę tam
, pójdę teraz
świetnie

Zmienne w długim ciągu jednowierszowym

string1 = "go"
string2 = "now"
string3 = "great"

singleline_string = (f"I will {string1} there. "
                     f"I will go {string2}. "
                     f"{string3}.")

print(singleline_string)

Pójdę tam. Pójdę teraz. świetny.


Alternatywnie możesz również utworzyć wielowierszowy f-string z potrójnymi cudzysłowami.

multiline_string = f"""I will {string1} there.
I will go {string2}.
{string3}."""
Stevoisiak
źródło
Dzięki temu Twój kod źródłowy wygląda ładnie, aw wersjach starszych niż Python 3.6 możesz uzyskać ten sam efekt, robiąc to (dodatkowy zestaw nawiasów i użycie +do konkatenacji): stackoverflow.com/a/54564926/4561887
Gabriel Staples
Triple cytowanie jest bardzo korzystna. Powinieneś najpierw przedstawić ten formularz.
jpmc26
@ jpmc26 Najpierw przedstawiłem w nawiasach w oparciu o wytyczne PEP 8 dotyczące wcięć w kodzie . Dlaczego preferowane byłoby potrójne cytowanie?
Stevoisiak
10

To jest to, czego chcesz:

>>> string1 = "go"
>>> string2 = "now"
>>> string3 = "great"
>>> mystring = """
... I will {string1} there
... I will go {string2}
... {string3}
... """
>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, 'string3': 'great', '__package__': None, 'mystring': "\nI will {string1} there\nI will go {string2}\n{string3}\n", '__name__': '__main__', 'string2': 'now', '__doc__': None, 'string1': 'go'}
>>> print(mystring.format(**locals()))

I will go there
I will go now
great
Havok
źródło
Zwróć uwagę, że potrójne cudzysłowy """zachowują znaki nowej linii, co oznacza, że ​​istnieje dodatkowy mystring
znak
Możesz użyć .strip(), .rstrip()lub .lstrip(), lub użyć luzu wewnątrz potrójnych cudzysłowów, aby uniknąć tworzenia nowej linii. mystring = "" "\ ABC \" ""
Havok
6

Do słownika można przekazać format(), każda nazwa klucza stanie się zmienną dla każdej skojarzonej wartości.

dict = {'string1': 'go',
        'string2': 'now',
        'string3': 'great'}

multiline_string = '''I'm will {string1} there
I will go {string2}
{string3}'''.format(**dict)

print(multiline_string)


Można również przekazać listę format(), numer indeksu każdej wartości zostanie użyty jako zmienne w tym przypadku.

list = ['go',
        'now',
        'great']

multiline_string = '''I'm will {0} there
I will go {1}
{2}'''.format(*list)

print(multiline_string)


Oba powyższe rozwiązania dadzą to samo:

Pójdę tam
, pójdę teraz
świetnie

jesterjunk
źródło
1

f-stringi , zwane także „sformatowanymi literałami łańcuchowymi”, są literałami łańcuchowymi, które mają fna początku znak; i nawiasy klamrowe zawierające wyrażenia, które zostaną zastąpione ich wartościami.

Ciągi f są oceniane w czasie wykonywania.

Możesz więc przepisać swój kod jako:

string1="go"
string2="now"
string3="great"
print(f"""
I will {string1} there
I will go {string2}
{string3}
""")

A to da następującą ocenę:

I will go there
I will go now
great

Możesz dowiedzieć się więcej na ten temat tutaj .

Anshika Singh
źródło
0

Jeśli ktoś przyszedł tutaj z klienta python-graphql, szukając rozwiązania do przekazania obiektu jako zmiennej, oto czego użyłem:

query = """
{{
  pairs(block: {block} first: 200, orderBy: trackedReserveETH, orderDirection: desc) {{
    id
    txCount
    reserveUSD
    trackedReserveETH
    volumeUSD
  }}
}}
""".format(block=''.join(['{number: ', str(block), '}']))

 query = gql(query)

Upewnij się, że nie używasz wszystkich nawiasów klamrowych, tak jak ja: „{{", "}}"

Radu Ciobanu
źródło