2014-05-01 12 views
6

Sto cercando di mantenere la pluralizzazione delle stringhe esistenti il ​​più semplice possibile e mi chiedevo se fosse possibile ottenere str.format() per interpretare un valore predefinito durante la ricerca di kwargs . Ecco un esempio:Valori kwarg predefiniti per il metodo str.format() di Python

string = "{number_of_sheep} sheep {has} run away" 
dict_compiled_somewhere_else = {'number_of_sheep' : 4, 'has' : 'have'} 

string.format(**dict_compiled_somewhere_else) 
# gives "4 sheep have run away" 

other_dict = {'number_of_sheep' : 1} 
string.format(**other_dict) 
# gives a key error: u'has' 
# What I'd like is for format to somehow default to the key, or perhaps have some way of defining the 'default' value for the 'has' key 
# I'd have liked: "1 sheep has run away" 

Acclamazioni

+1

correlati: [Plural String Formattazione] (http://stackoverflow.com/questions/21872366/plurale-stringa-formattazione) –

+0

Nice link, avrei dovuto vederlo prima – Patrick

+0

Vedi anche: https://stackoverflow.com/questions/20248355/how-to-get-python-to-gracefully-format-none-and -non-campi-esistenti – dreftymac

risposta

10

Come PEP 3101, string.format(**other_dict) non è disponibile.

Se l'indice o parola si riferisce a un elemento che non esiste, allora un IndexError/KeyError dovrebbe essere aumentata.

Un suggerimento per risolvere il problema è in Customizing Formatters, PEP 3101. Quello usa string.Formatter.

migliorano l'esempio nella PEP 3101:

from string import Formatter 

class UnseenFormatter(Formatter): 
    def get_value(self, key, args, kwds): 
     if isinstance(key, str): 
      try: 
       return kwds[key] 
      except KeyError: 
       return key 
     else: 
      return Formatter.get_value(key, args, kwds) 

string = "{number_of_sheep} sheep {has} run away" 
other_dict = {'number_of_sheep' : 1} 

fmt = UnseenFormatter() 
print fmt.format(string, **other_dict) 

L'uscita è

1 sheep has run away 
+1

Penso che questo sia il metodo più chiaro, diverso da quelli mostrati in [thread di ieri] (https://stackoverflow.com/questions/21872366/plural-string-formatting). Nel mio commento ho apportato alcune modifiche per rendere un po 'più DRY – Patrick

+2

PS un link a PEP 3101 sarebbe stato bello, e garantito un +1 ;-) – Patrick

+1

'return' manca prima di' Formatter.get_value (key, args , kwds) ', gli argomenti posizionali non funzionano senza quello. Inoltre, non penso che sia necessario implementare '__init__', poiché chiama solo' __init__' del genitore. –

0

Non riesco a vedere il vantaggio. È necessario controllare la pluralità comunque, causare normalmente non si dispone di un numero fisso di pecore

class PluralVerb(object): 
    EXCEPTIONS = {'have': 'has'} 
    def __init__(self, plural): 
     self.plural = plural 

    def __format__(self, verb): 
     if self.plural: 
      return verb 
     if verb in self.EXCEPTIONS: 
      return self.EXCEPTIONS[verb] 
     return verb+'s' 

number_of_sheep = 4 
print "{number_of_sheep} sheep {pl:run} away".format(number_of_sheep=number_of_sheep, pl=PluralVerb(number_of_sheep!=1)) 
print "{number_of_sheep} sheep {pl:have} run away".format(number_of_sheep=number_of_sheep, pl=PluralVerb(number_of_sheep!=1)) 
+0

Questo è bello e ASCIUTTO (singolare/plurale sono definiti in anticipo), ma personalmente preferirei definire il singolare nella mia stringa di formato e avere il plurale sostituito se necessario. Mostra un altro metodo per mskimm's – Patrick

1

Sulla base mskimm e Daniel risposta, ecco una soluzione che predefinisce le parole singolari/plurali (mentre la correzione di un paio di errori di battitura in mskimm's).

L'unico inconveniente è la codifica dura la parola arg number (in modo da non posso più usare number_of_sheep)

from string import Formatter 

class Plural(Formatter): 
    PLURALS = {'has' : 'have'} 
    def __init__(self): 
     super(Plural, self).__init__() 

    def get_value(self, key, args, kwds): 
     if isinstance(key, str): 
      try: 
       return kwds[key] 
      except KeyError: 
       if kwds.get('number', 1) == 1: 
        return key 
       return self.PLURALS[key] 
     return super(Plural, self).get_value(key, args, kwds) 

string = "{number} sheep {has} run away" 
fmt = Plural() 
print fmt.format(string, **{'number' : 1}) 
print fmt.format(string, **{'number' : 2}) 
+0

Una bella soluzione. Pensavo che la domanda riguardasse la sostituzione "sicura" e non "plurale". – emeth

+0

Immagino che tu abbia ragione, ho detto che si riferisce alla sostituzione sicura, ma il mio caso era per l'uso dei plurali. Tuttavia, la tua risposta ha ottenuto il segno di spunta :) – Patrick

Problemi correlati