Esiste un Python equivalente all'interpolazione di stringhe di Ruby?


343

Esempio di rubino:

name = "Spongebob Squarepants"
puts "Who lives in a Pineapple under the sea? \n#{name}."

La concatenazione di stringhe Python di successo mi sembra molto dettagliata.


2
Il problema qui è che si nametratta di una variabile locale che si trova nella stringa e in Python è necessario passare esplicitamente il dizionario delle variabili locali al formattatore di stringhe se si desidera che le utilizzi.
Katriel,

Questo non era il problema originale, ma grazie. Il tuo commento mi ha permesso di comprendere meglio l'ambito variabile (qualcosa con cui sto ancora guadagnando terreno). :)
Casta,

1
Cosa ne pensi di questo, allora? stackoverflow.com/questions/16504732/...
salchipapa


2
Vedi stackoverflow.com/a/33264516/55721 per questa funzione esatta in 3.6
dss539

Risposte:


413

Python 3.6 aggiungerà un'interpolazione letterale di stringhe simile all'interpolazione di stringhe di Ruby. A partire da quella versione di Python (che dovrebbe essere rilasciata entro la fine del 2016), sarai in grado di includere espressioni in "f-string", ad es.

name = "Spongebob Squarepants"
print(f"Who lives in a Pineapple under the sea? {name}.")

Prima del 3.6, il più vicino a questo è

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? %(name)s." % locals())

L' %operatore può essere utilizzato per l'interpolazione di stringhe in Python. Il primo operando è la stringa da interpolare, il secondo può avere diversi tipi tra cui una "mappatura", mappando i nomi dei campi sui valori da interpolare. Qui ho usato il dizionario delle variabili locali locals()per mappare il nome del campo nameal suo valore come variabile locale.

Lo stesso codice che utilizza il .format()metodo delle versioni recenti di Python sarebbe simile al seguente:

name = "Spongebob Squarepants"
print("Who lives in a Pineapple under the sea? {name!s}.".format(**locals()))

C'è anche la string.Templateclasse:

tmpl = string.Template("Who lives in a Pineapple under the sea? $name.")
print(tmpl.substitute(name="Spongebob Squarepants"))

@Caste vedi qui: docs.python.org/library/stdtypes.html#string-formatting e pubblica un commento di follow-up se hai bisogno di ulteriori dettagli
mikej

Capisco l'essenza di base di esso, tuttavia non capisco completamente tutti i simboli e il testo aggiuntivi trovati nell'esempio nella documentazione. Perché l'uso di convert in stringa qui:% (lingua) s Cosa significa 3 in '03d'? Perché dopo la stringa c'è% \? Anche l'assegnazione delle variabili (se in realtà sono variabili) dopo l'espressione di stampa mi confonde. Scusa se questo è un dolore!
Casta,

1
I due formati di base utilizzati nell'esempio sono %sper una stringa e %03dper un numero imbottito di 3 cifre con zeri iniziali. Potrebbe essere solo scritto print "%s has %03d" % ("Python", 2). L'esempio utilizza quindi l'inserimento di una chiave di mappatura tra parentesi dopo la %quale è un modo per assegnare ai segnaposto nomi significativi anziché fare affidamento sul loro ordine nella stringa. Quindi si passa un dizionario che associa i nomi delle chiavi ai loro valori. Ecco perché Sven sta usando la locals()funzione che restituisce un dict contenente tutte le variabili locali in modo da mappare namesul valore del nome
mikej

L'uso richiesto di un tipo di conversione è stato ciò che mi ha confuso per primo. Quindi, usando la terminologia della documentazione. % Avvia l'identificatore. Non esiste un flag di conversione per (lingua), ma solo un tipo di conversione (le "s" finali); (numero) ha tuttavia uno (o due) flag di conversione che è rispettivamente "0" (e "3"). La 'd' è il tipo di conversione e indica che è un numero intero. Ho capito bene?
Casta,

@Caste: Sì, è praticamente giusto. Nota che puoi sempre usare un stipo di conversione: Python può convertire qualsiasi cosa in una stringa. Ma ovviamente perderai le speciali capacità di formattazione di altri tipi di conversione.
Sven Marnach,

143

Da Python 2.6.X potresti voler usare:

"my {0} string: {1}".format("cool", "Hello there!")

27
Si noti che l' %operatore per l'interpolazione di stringhe non è obsoleto in Python 3.x. docs.python.org/dev/py3k/whatsnew/… annuncia il piano di deprezzamento a %partire dalla 3.1, ma ciò non è mai accaduto.
Sven Marnach,

8
% -syntax continua a vivere in Python 3 (non deprecato a partire da Python 3.2)
Corey Goldberg,

9
Solo una nota: il numero in {}può essere eliminato.
disegna il

32

Ho sviluppato il pacchetto interpy , che abilita l'interpolazione di stringhe in Python .

Basta installarlo tramite pip install interpy. E poi, aggiungi la riga # coding: interpyall'inizio dei tuoi file!

Esempio:

#!/usr/bin/env python
# coding: interpy

name = "Spongebob Squarepants"
print "Who lives in a Pineapple under the sea? \n#{name}."

3
Questo sembra davvero insicuro.
d33tah,

@ d33tah: No, purché le stringhe siano note al momento della compilazione.
Clément

28

L'interpolazione di stringhe di Python è simile a C's printf ()

Se provi:

name = "SpongeBob Squarepants"
print "Who lives in a Pineapple under the sea? %s" % name

Il tag %sverrà sostituito con la namevariabile. Dovresti dare un'occhiata ai tag delle funzioni di stampa: http://docs.python.org/library/functions.html


1
come posso fare in questo modo con 2 variabili?
Julio Marins,

16
@JulioMarins Usare una tupla: print "First is %s, second is %s" % (var1, var2).
kirbyfan64sos,

28

L'interpolazione di stringhe verrà inclusa in Python 3.6 come specificato in PEP 498 . Sarai in grado di fare questo:

name = 'Spongebob Squarepants'
print(f'Who lives in a Pineapple under the sea? \n{name}')

Nota che odio Spongebob, quindi scrivere questo è stato leggermente doloroso. :)


Grazie per quel riferimento Spongebob (/ disgusto): devo votarlo adesso.
javadba,


3
import inspect
def s(template, **kwargs):
    "Usage: s(string, **locals())"
    if not kwargs:
        frame = inspect.currentframe()
        try:
            kwargs = frame.f_back.f_locals
        finally:
            del frame
        if not kwargs:
            kwargs = globals()
    return template.format(**kwargs)

Uso:

a = 123
s('{a}', locals()) # print '123'
s('{a}') # it is equal to the above statement: print '123'
s('{b}') # raise an KeyError: b variable not found

PS: le prestazioni potrebbero essere un problema. Ciò è utile per gli script locali, non per i log di produzione.

duplicato:


2

Per il vecchio Python (testato su 2.4) la soluzione migliore indica la strada. Puoi farlo:

import string

def try_interp():
    d = 1
    f = 1.1
    s = "s"
    print string.Template("d: $d f: $f s: $s").substitute(**locals())

try_interp()

E tu ottieni

d: 1 f: 1.1 s: s

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.