f-string %d - Posso importare i letterali di stringa formattati di Python's 3.6(stringhe di f)nel vecchio 3.x, 2.x Python?




front of (5)

I nuovi f-string Python 3.6 mi sembrano un enorme salto nell'usabilità delle stringhe, e mi piacerebbe entrare e adottarli con tutto il cuore su nuovi progetti che potrebbero essere eseguiti su interpreti più vecchi. 2.7, il supporto per 3.3-3.5 sarebbe ottimo ma per lo meno mi piacerebbe usarli nelle basi di codice Python 3.5. Come posso importare i letterali di stringa formattati da 3.6 per gli interpreti più vecchi?

Capisco che i letterali stringa formattati come f"Foo is {age} {units} old" non stiano cambiando le modifiche, quindi non verrebbero inclusi in una chiamata from __future__ import ... Ma il cambiamento non è retro-porting (AFAIK) avrei bisogno di essere sicuro che qualunque nuovo codice che scrivo con f-strings è eseguito solo su Python 3.6+, che è un rompicapo per molti progetti.


Answers

Ho appena scritto un compilatore back-port per la stringa f , chiamato f2format . Proprio come richiesto, puoi scrivere letterali di f-string in Python 3.6 e compilare una versione compatibile per l'esecuzione da parte degli utenti finali, proprio come Babel per JavaScript.

f2format fornisce una soluzione intelligente, ma imperfetta, di un compilatore back-port . Sostituisce i letterali f-string con i metodi str.format , mantenendo il layout originale del codice sorgente. Puoi semplicemente usare

f2format /path/to/the/file_or_directory

che riscriverà tutti i file Python sul posto. Per esempio,

var = f'foo{(1+2)*3:>5}bar{"a", "b"!r}boo'

sarà convertito a

var = ('foo{:>5}bar{!r}boo').format(((1+2)*3), ("a", "b"))

La concatenazione di stringhe, la conversione, la specifica di formato, le multi-linee e gli unicodes sono tutti trattati correttamente. Inoltre, f2format file originali nel caso ci siano delle violazioni della sintassi.


Le stringhe di f sono create dall'interprete sul token del prefisso f - quella sola funzione ucciderà qualsiasi possibilità di compatibilità.

Il tuo colpo più vicino è quello di utilizzare la formattazione della parola chiave, come

'Foo is {age} {units} old'.format(age=age, units=units)

che può essere più facilmente rifattorizzato al termine del requisito di compatibilità.


ecco cosa uso:

text = "Foo is {age} {units} old".format(**locals())

scompatta ( ** ) il dict restituito dai locals() che ha tutte le variabili locali come dict {variable_name: value} nome_variabile {variable_name: value}

Nota che questo non funzionerà con le variabili dichiarate in un ambito esterno, a meno che tu non lo implementi all'ambito locale con nonlocal (Python 3.0+).

puoi anche usare

text.format(**locals(),**globals())

per includere variabili globali nella stringa.


Sfortunatamente se vuoi usarlo devi richiedere Python 3.6+ , lo stesso con l'operatore di moltiplicazione della matrice @ e Python 3.5+ o yield from ( Python 3.4+ penso)

Questi hanno apportato modifiche al modo in cui il codice viene interpretato e quindi generano SyntaxErrors quando importati in versioni precedenti. Ciò significa che devi metterli da qualche parte dove questi non sono importati nei vecchi Python o custoditi da un eval o da un exec (non consiglierei questi ultimi due!).

Quindi sì, hai ragione, se vuoi supportare più versioni di Python non puoi usarle facilmente.


Prova a fare questo:

x = " {{ Hello }} {0} "
print x.format(42)




python string f-string