Est-il possible d'effectuer un formatage de chaîne partiel avec les méthodes de formatage de chaîne avancées, similaire au modèle de chaîne safe_substitute()
?
Par exemple:
s = '{foo} {bar}'
s.format(foo='FOO') #Problem: raises KeyError 'bar'
Est-il possible d'effectuer un formatage de chaîne partiel avec les méthodes de formatage de chaîne avancées, similaire au modèle de chaîne safe_substitute()
?
Par exemple:
s = '{foo} {bar}'
s.format(foo='FOO') #Problem: raises KeyError 'bar'
Vous pouvez le piéger en un formatage partiel en écrasant le mappage:
import string
class FormatDict(dict):
def __missing__(self, key):
return "{" + key + "}"
s = '{foo} {bar}'
formatter = string.Formatter()
mapping = FormatDict(foo='FOO')
print(formatter.vformat(s, (), mapping))
impression
FOO {bar}
Bien entendu, cette implémentation de base ne fonctionne correctement que dans des cas simples.
Cette limitation de l' .format()
- l'impossibilité de faire des substitutions partielles - a été mise sur écoute-moi.
Après l'évaluation de l'écriture personnalisée Formatter
classe comme décrit dans beaucoup de réponses ici, et même en tenant compte de l'aide de paquets de tierce partie tels que lazy_format, j'ai découvert beaucoup plus simple intégré de la solution: chaînes du Modèle
Il offre des fonctionnalités similaires, mais fournit également une substitution partielle approfondie safe_substitute()
méthode. Le modèle des chaînes besoin d'avoir un $
préfixe (qui se sent un peu bizarre, mais l'ensemble de la solution, je pense que c'est mieux).
import string
template = string.Template('${x} ${y}')
try:
template.substitute({'x':1}) # raises KeyError
except KeyError:
pass
# but the following raises no error
partial_str = template.safe_substitute({'x':1}) # no error
# partial_str now contains a string with partial substitution
partial_template = string.Template(partial_str)
substituted_str = partial_template.safe_substitute({'y':2}) # no error
print substituted_str # prints '12'
Formé d'un confort wrapper sur cette base:
class StringTemplate(object):
def __init__(self, template):
self.template = string.Template(template)
self.partial_substituted_str = None
def __repr__(self):
return self.template.safe_substitute()
def format(self, *args, **kws):
self.partial_substituted_str = self.template.safe_substitute(*args, **kws)
self.template = string.Template(self.partial_substituted_str)
return self.__repr__()
>>> s = StringTemplate('${x}${y}')
>>> s
'${x}${y}'
>>> s.format(x=1)
'1${y}'
>>> s.format({'y':2})
'12'
>>> print s
12
De même, un wrapper basé sur Sven réponse qui utilise la valeur par défaut de la chaîne de mise en forme:
class StringTemplate(object):
class FormatDict(dict):
def __missing__(self, key):
return "{" + key + "}"
def __init__(self, template):
self.substituted_str = template
self.formatter = string.Formatter()
def __repr__(self):
return self.substituted_str
def format(self, *args, **kwargs):
mapping = StringTemplate.FormatDict(*args, **kwargs)
self.substituted_str = self.formatter.vformat(self.substituted_str, (), mapping)
Si vous définissez vos propres Formatter
qui remplace l' get_value
méthode, vous pouvez l'utiliser pour la carte undefined noms de champ pour tout ce que tu voulais:
http://docs.python.org/library/string.html#string.Formatter.get_value
Par exemple, vous pouvez mapper bar
de "{bar}"
si bar
n'est pas dans la kwargs.
Cependant, ce qui nécessite l'utilisation de l' format()
méthode de votre objet de Formatage, pas la chaîne de l' format()
méthode.
Grâce au commentaire d’ Amber , j’ai trouvé ceci:
class PartialFormatter(string.Formatter):
def get_field(self, field_name, args, kwargs):
try:
val = super(PartialFormatter, self).get_field(field_name, args, kwargs)
except (KeyError, AttributeError):
first, _ = field_name._formatter_field_name_split()
val = '{' + field_name + '}', first
return val
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.