2012-04-15 17 views
5

Recentemente, ho trovato la funzione ''.format molto utile perché può migliorare la leggibilità paragonandola alla formattazione %. cercando di raggiungere semplice formattazione di stringhe:funzione ".format" di python

data = {'year':2012, 'month':'april', 'location': 'q2dm1'} 

year = 2012 
month = 'april' 
location = 'q2dm1' 
a = "year: {year}, month: {month}, location: {location}" 
print a.format(data) 
print a.format(year=year, month=month, location=location) 
print a.format(year, month, location) 

mentre due prime stampe si formattano come mi aspetto (sì, something=something sembra brutto, ma questo è solo un esempio), l'ultimo solleverebbe KeyError: 'year'. C'è qualche trucco in python per creare un dizionario in modo che riempia automaticamente le chiavi e i valori, ad esempio somefunc(year, month, location) restituirà {'year':year, 'month': month, 'location': location}?

Sono abbastanza nuovo per Python e non sono riuscito a trovare alcuna informazione su questo argomento, tuttavia un trucco come questo avrebbe migliorato e ridotto drasticamente il mio codice corrente.

Grazie in anticipo e scusami il mio inglese.

risposta

6

Il primo print dovrebbe essere

print a.format(**data) 

Inoltre, se si stanno trovando alcune scorciatoie, si potrebbe scrivere uno come, c'è grande differenza.

def trans(year, month, location): 
    return dict(year=year, month=month, location=location) 
+0

Sembra che non ci sia modo di ridurre questo codice ripetitivo :) La funzione è buona ed è stato quello che ho fatto, in realtà, ma in seguito ho trovato difficile da sostenere perché con un sacco di argomenti che mi servivano per cambiare codice in diversi punti, che risultò essere persino peggiore di quello che effettivamente creavo a mano. –

+0

@duke_nukem sì dipende dall'utilizzo effettivo. Il codice è buono e il formato api è abbastanza chiaro. Se sei in grado di ottenere qualcosa come 'format (* args, ** kwargs)', potrebbe anche essere fatto, ma non penso che potrebbe rendere le cose più facili. – okm

1

È possibile utilizzare il dict() callable:

dict(year=yeah, month=month, location=location) 

Quando si passa argomenti a parola chiave che crea un dict contenente gli elementi specificati come kwargs.

Se non si desidera specificare i nomi degli argomenti, utilizzare lo stile di posizione di .format():

>>> a = 'year {0} month {1} location {2}' 
>>> print a.format(2012, 'april', 'abcd') 
year 2012 month april location abcd 

Tuttavia, se si tenta di fare qualcosa di simile a ciò che compact() in PHP fa (creare un nomi di variabili mappatura dict a i suoi valori senza specificare nome e variabile separatamente), per favore non farlo. Produce solo un codice brutto e illeggibile e richiederebbe comunque degli hacker cattivi.

+0

Sì, io sono a conoscenza di dict() ma sto cercando di evitare il codice non necessario e ridurlo un po '. .format può accettare la tua opzione senza dict() a proposito. Grazie. –

+0

Grazie, è vicino a ciò di cui ho bisogno, tuttavia con 10-12 argomenti diventa piuttosto difficile navigare tra gli indici. –

+0

Bene in questo caso si suppone che si usi la sintassi dict. Tuttavia, in base a ciò che si vuole fare, si consideri l'utilizzo di un motore di template reale come [jinja2] (http://jinja.pocoo.org/). – ThiefMaster

1

Si potrebbe passare locals():

a.format(**locals()) 

Naturalmente, questo ha problemi: si dovrà passare tutto in locali, e può essere difficile da capire l'effetto di rinominare o rimuovere una variabile .

Un modo migliore sarebbe:

a.format(**{k:v for k,v in locals() if k in ('year', 'month')}) 
# or; note that if you move the lambda expression elsewhere, you will get a different result 
a.format(**(lambda ld = locals(): {k:ld[k] for k in ('year', 'month')})()) 

Ma questo non è più conciso, a meno che non si avvolge in su con una funzione (che deve ovviamente prendere un parametro dict).

3
data = {'year':2012, 'month':'april', 'location': 'q2dm1'} 
a = "year: {year}, month: {month}, location: {location}" 

print a.format(**data) 

..è quello che stai cercando. È funzionalmente identico a fare .format(year=data['year'], ...), o gli altri esempi che hai dato.

La cosa a doppio asterisco è una cosa difficile da cercare, quindi viene solitamente definita "kwargs".Ecco un good SO question on this syntax

0

Come di Python 3.6, è anche possibile utilizzare la nuova Formatted string literals (f-strings), che è possibile utilizzare con variabili:

year = 2012 
month = 'april' 
location = 'q2dm1' 
a = f"year: {year}, month: {month}, location: {location}" 
print(a) 

o un dizionario:

data = {'year': 2012, 'month': 'april', 'location': 'q2dm1'} 
a = f"year: {data['year']}, month: {data['month']}, location: {data['location']}" 
print(a) 

nota la f prefisso prima della stringa letterale.

PEP 498: Formatted string literals:

letterali stringa formattata hanno il prefisso 'f' e sono simili alle stringhe di formato accettati da str.format(). Contengono i campi di sostituzione circondati da parentesi graffe. I campi di sostituzione sono espressioni, che vengono valutati in fase di esecuzione, e poi formattati utilizzando il formato() Protocollo:

>>> 
>>> name = "Fred" 
>>> f"He said his name is {name}." 
'He said his name is Fred.' 
>>> width = 10 
>>> precision = 4 
>>> value = decimal.Decimal("12.34567") 
>>> f"result: {value:{width}.{precision}}" # nested fields 
'result:  12.35' 

...