I molti modi di formattazione delle stringhe di Python: quelli più vecchi (saranno) deprecati?


106

Python ha almeno sei modi per formattare una stringa:

In [1]: world = "Earth"

# method 1a
In [2]: "Hello, %s" % world
Out[2]: 'Hello, Earth'

# method 1b
In [3]: "Hello, %(planet)s" % {"planet": world}
Out[3]: 'Hello, Earth'

# method 2a
In [4]: "Hello, {0}".format(world)
Out[4]: 'Hello, Earth'

# method 2b
In [5]: "Hello, {planet}".format(planet=world)
Out[5]: 'Hello, Earth'

# method 2c
In [6]: f"Hello, {world}"
Out[6]: 'Hello, Earth'

In [7]: from string import Template

# method 3
In [8]: Template("Hello, $planet").substitute(planet=world)
Out[8]: 'Hello, Earth'

Breve storia dei diversi metodi:

  • printfla formattazione in stile esiste dall'infanzia di Pythons
  • La Templateclasse è stata introdotta in Python 2.4
  • Il formatmetodo è stato introdotto in Python 2.6
  • f-strings sono state introdotte in Python 3.6

Le mie domande sono:

  • La printfformattazione in stile è deprecata o sarà deprecata?
  • In Template class, il substitutemetodo è deprecato o sarà deprecato? (Non sto parlando safe_substitute, che a quanto ho capito offre funzionalità uniche)

Domande simili e perché penso che non siano duplicati:

Guarda anche


1
Devo far notare che hai dimenticato la Formatterlezione?
Martijn Pieters

Risposte:


14

Sebbene ci siano varie indicazioni nei documenti che .formate le stringhe f siano superiori alle %stringhe, non esiste un piano superstite per deprecare queste ultime.

Nel problema di commit # 14123: menziona esplicitamente che la formattazione della stringa% vecchio stile ha delle avvertenze ma non scomparirà presto. , ispirato al problema Indica che non ci sono attualmente piani per deprecare la formattazione in stile printf , i documenti su %-formatting sono stati modificati per contenere questa frase:

Poiché la nuova sintassi di formattazione delle stringhe è più flessibile e gestisce le tuple ei dizionari in modo naturale, è consigliata per il nuovo codice. Tuttavia, non ci sono attualmente piani per deprecare la formattazione in stile printf .

(Enfasi mia.)

Questa frase è stata rimossa in seguito, nel commit Close # 4966: revamp the sequence docs per spiegare meglio lo stato del moderno Python . Questo potrebbe sembrare un segno che un piano per deprecare la %formattazione era tornato sulle carte ... ma immergersi nel bug tracker rivela che l'intento era l'opposto. Sul bug tracker, l'autore del commit caratterizza il cambiamento in questo modo :

  • ha cambiato la prosa che descrive la relazione tra la formattazione in stile printf e il metodo str.format (rimuovendo deliberatamente l'implicazione che il primo è un vero pericolo di scomparsa - semplicemente non è pratico per noi considerare seriamente di ucciderlo)

In altre parole, abbiamo apportato due modifiche consecutive ai %documenti di formattazione intesi a sottolineare esplicitamente che non sarà deprecato, figuriamoci rimosso. I documenti rimangono supponenti sui relativi meriti dei diversi tipi di formattazione delle stringhe, ma sono anche chiari che la %formattazione non verrà deprecata o rimossa.

Inoltre, l' ultima modifica a quel paragrafo , nel marzo 2017, lo ha cambiato da questo ...

Le operazioni di formattazione descritte qui mostrano una serie di stranezze che portano a una serie di errori comuni (come la mancata visualizzazione corretta di tuple e dizionari). L'utilizzo delle stringhe letterali formattate più recenti o str.formatdell'interfaccia consente di evitare questi errori. Queste alternative forniscono anche approcci più potenti, flessibili ed estensibili alla formattazione del testo.

... a questa:

Le operazioni di formattazione descritte qui mostrano una serie di stranezze che portano a una serie di errori comuni (come la mancata visualizzazione corretta di tuple e dizionari). L'utilizzo delle stringhe letterali formattate più recenti, str.formatdell'interfaccia o delle stringhe del modello può aiutare a evitare questi errori. Ciascuna di queste alternative fornisce i propri compromessi e vantaggi di semplicità, flessibilità e / o estensibilità.

Notare il passaggio da "aiuta a evitare" a "può aiutare a evitare", e come la chiara raccomandazione di .formatstringhe e f è stata sostituita da una prosa equivoca e soffice su come ogni stile "fornisce i propri compromessi e vantaggi" . Cioè, non solo una deprecazione formale non è più disponibile, ma i documenti attuali stanno apertamente riconoscendo che la %formattazione ha almeno alcuni "vantaggi" rispetto agli altri approcci.

Da tutto ciò deduco che il movimento per deprecare o rimuovere la %formattazione non solo ha vacillato, ma è stato completamente e definitivamente sconfitto.


2
Il soffice cambio di lingua è stato aggiunto per placare i manutentori di Mercurial (tra gli altri) che non volevano vedere Mercurial lasciato indietro con una base di codice troppo grande per sradicarne l'uso %. Ora che la politica "nessuna modifica del codice su larga scala" è stata eliminata, anche le loro obiezioni stanno svanendo. A lungo termine, mantenendo entrambe le forme senza alcun vantaggio rimanente, % a un certo punto la sintassi printf verrà comunque rimossa. Non sappiamo ancora quando, quindi valeva la pena attenuare la lingua.
Martijn Pieters

@MartijnPieters Interessante. Sembra che tu abbia una grande conoscenza di questa decisione che mi manca. Per quello che vale, penso che una tua risposta ben referenziata che delinei questi punti (come una nuova risposta o una modifica a quella esistente) avrebbe valore.
Mark Amery

58

Il nuovo .format()metodo ha lo scopo di sostituire la vecchia %sintassi di formattazione. Quest'ultimo è stato de-enfatizzato, (ma non ancora ufficialmente deprecato ). La documentazione del metodo afferma quanto segue:

Questo metodo di formattazione delle stringhe è il nuovo standard in Python 3 e dovrebbe essere preferito alla %formattazione descritta in Operazioni di formattazione delle stringhe nel nuovo codice.

(Enfasi mia).

Per mantenere la compatibilità con le versioni precedenti e per rendere la transizione più facile, il vecchio formato è stato lasciato al suo posto per ora . Dalla proposta originale PEP 3101 :

Compatibilità all'indietro

La compatibilità con le versioni precedenti può essere mantenuta lasciando i meccanismi esistenti in atto. Il nuovo sistema non entra in conflitto con nessuno dei nomi dei metodi delle tecniche di formattazione delle stringhe esistenti, quindi entrambi i sistemi possono coesistere fino a quando non arriva il momento di deprecare il vecchio sistema.

Nota finché non arriva il momento di deprecare il vecchio sistema ; non è stato deprecato, ma il nuovo sistema deve essere utilizzato ogni volta che scrivi nuovo codice .

Il nuovo sistema ha come vantaggio la possibilità di combinare l'approccio tupla e dizionario del vecchio %formattatore:

"{greeting}, {0}".format(world, greeting='Hello')

ed è estensibile tramite l' object.__format__()hook utilizzato per gestire la formattazione dei singoli valori.

Si noti che il vecchio sistema aveva %e la Templateclasse, dove quest'ultima consente di creare sottoclassi che aggiungono o alterano il suo comportamento. Il nuovo sistema di stile ha la Formatterclasse per riempire la stessa nicchia.

Python 3 si è allontanato ulteriormente dalla deprecazione, dandoti invece un avviso nella sezione printfFormattazione stringa in stile :

Nota : le operazioni di formattazione descritte qui mostrano una serie di stranezze che portano a una serie di errori comuni (come la mancata visualizzazione corretta di tuple e dizionari). L'utilizzo delle stringhe letterali formattate più recenti o str.format()dell'interfaccia consente di evitare questi errori. Queste alternative forniscono anche approcci più potenti, flessibili ed estensibili alla formattazione del testo.

Python 3.6 ha anche aggiunto letterali stringa formattati , che allineano le espressioni nelle stringhe di formato. Questi sono il metodo più veloce per creare stringhe con valori interpolati e dovrebbero essere usati al posto di str.format()dove puoi usare un letterale.


4
E con Formatterpuoi creare formati personalizzati come quelli datetimeutilizzati dagli oggetti. Inoltre, poiché .formatè una funzione, puoi usarla per creare una formattazione pigra richiamabile in modo più diretto: ad esempio,fmt = '{} - {}'.format; fmt(a, b)
Jon Clements

Non vedo come Templatesia correlato %o al vecchio sistema . In particolare il PEP che collega gli stati Sebbene vi sia una certa sovrapposizione tra questa proposta e string.Template, si ritiene che ciascuna serva a un bisogno distinto e che l'una non ovvi all'altra. Nella tua risposta si può essere confusi sul fatto che anche la Templateformattazione, essendo parte del vecchio sistema , è deprecata.
Bakuriu

@ Bakuriu: Giusto, penso di essermi perso quella parte; ma secondo me la Formatterclasse può soddisfare le stesse esigenze di string.Template().
Martijn Pieters

1
[...]should be preferred to the % formatting[...]questa parte è stata rimossa dalla documentazione. docs.python.org/3/library/stdtypes.html#str.format
AXO

Penso che questa risposta sia attualmente fuorviante; il primo passaggio citato è stato rimosso dalla documentazione di Python 3, e mi sembra abbastanza chiaro che non ci siano più intenti per una deprecazione. Questa risposta ha ancora un valore storico, ma sarei propenso a modificare la formulazione per evitare qualsiasi suggerimento che una deprecazione sia ancora nelle carte e a modificare gran parte della prima metà della risposta in modo che sia al passato. Lo farò io stesso ad un certo punto se non ti opponi, ma ho pensato di commentare prima per darti la possibilità di apportare tali modifiche tu stesso se lo desideri.
Mark Amery

45

L' %operatore per la formattazione delle stringhe non è deprecato e non verrà rimosso, nonostante le altre risposte.
Ogni volta che l'argomento viene sollevato nell'elenco di sviluppo di Python, c'è una forte controversia su quale sia il migliore, ma nessuna controversia sull'opportunità di rimuovere il modo classico: rimarrà. Nonostante fosse indicato su PEP 3101, Python 3.1 era andato e veniva, e la %formattazione è ancora in circolazione.

Le affermazioni per mantenere lo stile classico sono chiare: è semplice, è veloce, è veloce da fare per cose brevi. L'uso del .formatmetodo non è sempre più leggibile - e quasi nessuno - anche tra gli sviluppatori principali, può utilizzare la sintassi completa fornita da .formatsenza dover guardare il riferimento Anche nel 2009, si avevano messaggi come questo: http: // mail. python.org/pipermail/python-dev/2009-October/092529.html - l'argomento era appena apparso nelle liste da allora.

Aggiornamento 2016

Nell'attuale versione di sviluppo di Python (che diventerà Python 3.6) esiste un terzo metodo di interpolazione delle stringhe, descritto su PEP-0498 . Si definisce un nuovo prefisso citazione f""(oltre alla corrente u"", b""e r"").

Prefissando una stringa con fverrà chiamato un metodo sull'oggetto stringa in fase di esecuzione, che interpolerà automaticamente le variabili dall'ambito corrente nella stringa:

>>> value = 80
>>> f'The value is {value}.'
'The value is 80.'

3
È molto più bello consentire ai tipi di implementare i propri __format__. Ad esempio, format(Decimal('0.1'), '.20f')vs '%.20f' % Decimal('0.1'). Quest'ultimo costringe il decimale a un float.
Eryk Sun

2
NB. Non ho sostenuto che il vecchio stile sia migliore sotto tutti gli aspetti - solo che è più breve e talvolta più leggibile (e talvolta no). Certamente il nuovo modo è molto più flessibile.
jsbueno

C'è un equivalente per fin Python 3?
Daniel

Il f-stringscome usato sopra sono novità nella lingua di Python 3.6. Non esiste nelle versioni precedenti e solleverà un errore di sintassi su quelle.
jsbueno

20

L'ultima posizione di Guido su questo sembra essere indicata qui:

Novità di Python 3.0

PEP 3101: un nuovo approccio alla formattazione delle stringhe

Un nuovo sistema per le operazioni di formattazione delle stringhe incorporate sostituisce l'operatore di formattazione delle stringhe%. (Tuttavia, l'operatore% è ancora supportato; sarà deprecato in Python 3.1 e rimosso dal linguaggio in un secondo momento.) Leggi PEP 3101 per lo scoop completo.

E lo stesso PEP3101 , che ha l'ultima modifica che risale a (ven, 30 set 2011), quindi nessun progresso negli ultimi tempi, suppongo.


18

Guardando i vecchi documenti Python e PEP 3101 c'era una dichiarazione secondo cui l'operatore% sarebbe stato deprecato e rimosso dal linguaggio in futuro. La seguente dichiarazione era nei documenti Python per Python 3.0, 3.1 e 3.2:

Poiché str.format () è abbastanza nuovo, molto codice Python utilizza ancora l'operatore%. Tuttavia, poiché questo vecchio stile di formattazione verrà eventualmente rimosso dal linguaggio, in genere dovrebbe essere utilizzato str.format ().

Se vai alla stessa sezione nei documenti Python 3.3 e 3.4, vedrai che l'istruzione è stata rimossa. Inoltre, non riesco a trovare nessun'altra dichiarazione da nessun'altra parte nella documentazione che indichi che l'operatore sarà deprecato o rimosso dalla lingua. È anche importante notare che PEP3101 non è stato modificato in oltre due anni e mezzo (venerdì, 30 settembre 2011).

Aggiornare

PEP461 L'aggiunta della formattazione% a bytes e bytearray è accettata e dovrebbe far parte di Python 3.5 o 3.6. È un altro segno che l'operatore% è vivo e vegeto.

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.