[Python 2/3] Analyser la chaîne de format

Il existe actuellement trois types de fonctionnalités en Python qui sont équivalentes au sprintf de C. (La chaîne F est exclue car elle n'utilise pas de chaîne de format)

Nom? Comment utiliser
%-formatting fmt % values
str.format() fmt.format(*values) / fmt.format(**values)
Template strings string.Template(fmt).substitute(**values)

Cet article résume comment savoir combien d'éléments de tapple sont nécessaires dans la partie values du tableau ci-dessus, ou les clés du dictionnaire. Pour être honnête, je pense que c'est une connaissance assez rarement utilisée, mais cela peut être utile lorsque vous créez votre propre Formatter en héritant de logging.Formatter.

Aperçu

--% -formatting → Echec du formatage et voir l'exception.

%-formatting (printf style formatting) Contrairement aux deux autres, je ne trouve pas de fonction dédiée pour l'analyse dans le package standard, donc je ferai de mon mieux. Cette fois, j'ai créé une fonction pour déchiffrer en fonction de l'exception renvoyée. Si le type demandé dans la partie values de fmt% values est un taple, sa longueur est retournée, et s'il s'agit d'un dictionnaire, sa clé est retournée.

def parse_printf_style_format(fmt):
    if not isinstance(fmt, (bytes, str)):
        raise TypeError('got ' + type(fmt).__name__)
        
    try:
        fmt % ()
    except TypeError as e:
        if e.args[0] == 'not enough arguments for format string':
            values = ()
        elif e.args[0] == 'format requires a mapping':
            values = {}
        else:
            raise
    else:
        return None
    
    if isinstance(values, tuple):
        while True:
            try:
                fmt % values
            except TypeError as e:
                if e.args[0] == 'not enough arguments for format string':
                    values += (0,)
                else:
                    raise ValueError('invalid format: ' + repr(fmt))
            else:
                return len(values)
    elif isinstance(values, dict):
        while True:
            try:
                fmt % values
            except TypeError as e:
                if e.args[0] == 'not enough arguments for format string':
                    raise ValueError('invalid format: ' + repr(fmt))
                else:
                    raise
            except KeyError as e:
                values[e.args[0]] = 0
            else:
                return tuple(values.keys())
    else:
        assert False

Exemple d'utilisation

>>> parse_printf_style_format('%d %s %x')
3
>>> parse_printf_style_format('%(foo)s, %(bar)d')
('foo', 'bar')

str.format()

C'est un coup dur avec string.Formatter (). Parse (fmt). Pour plus de détails, reportez-vous au Document officiel.

>>> import string
>>> fmt = '{foo:s}, {{bar:d}}, and {:f}'
>>> list(string.Formatter().parse(fmt))
[('', 'foo', 's', None),
 (', {', None, None, None),
 ('bar:d}', None, None, None),
 (', and ', '', 'f', None)]

Template strings

C'est un coup dur avec string.Template.pattern.finditer (fmt). L'expression régulière qui correspond à l'espace réservé est stockée dans l'attribut pattern.

>>> import string
>>> fmt = '${this_is_braced} $$this_is_escaped $@this_is_invalid $this_is_named'
>>> print(string.Template.pattern.pattern)
    \$(?:
      (?P<escaped>\$) |   # Escape sequence of two delimiters
      (?P<named>[_a-z][_a-z0-9]*)      |   # delimiter and a Python identifier
      {(?P<braced>[_a-z][_a-z0-9]*)}   |   # delimiter and a braced identifier
      (?P<invalid>)              # Other ill-formed delimiter exprs
    )
>>> [match.groupdict() for match in string.Template.pattern.finditer(fmt)]
[{'braced': 'this_is_braced', 'escaped': None, 'invalid': None, 'named': None},
 {'braced': None, 'escaped': '$', 'invalid': None, 'named': None},
 {'braced': None, 'escaped': None, 'invalid': '', 'named': None},
 {'braced': None, 'escaped': None, 'invalid': None, 'named': 'this_is_named'}]

Impressions

Le traitement à froid du formatage «%» est terrible.

Recommended Posts

[Python 2/3] Analyser la chaîne de format
Format de chaîne Python
Format de chaîne Python
Indentation Python et format de chaîne
Format de chaîne avec l'opérateur Python%
Format de chaîne
Format de chaîne 2
Chaîne Python
[Python3] Mettre en forme la chaîne de caractères en utilisant le nom de la variable comme clé
Python: combinaison de chaînes
tranche de chaîne python
python: utilisez les variables définies dans le format de chaîne telles quelles
Échapper les crochets ondulés dans la chaîne de format
Type de chaîne Python2
Python # type de chaîne
format en python
Inversion de chaîne Python
[Introduction à Python] Comment écrire une chaîne de caractères avec la fonction format
Analysons le journal de validation git en Python!
[Python] matplotlib: Formatez le diagramme de votre mémoire
[Python] Comment changer le format de la date (format d'affichage)
json.dumping None en python renvoie la chaîne null
Format de séquence d'échappement de chaîne à Unicode pour Python
Trouvez le maximum de Python
Manipulation de chaîne en python
Analyser XML en Python
[Python] Assigner une chaîne sur plusieurs lignes
Maître de manipulation de chaînes Python
le zen de Python
python> datetime> Get datetime (par exemple 20151130) chaîne de format> print today.strftime ("% Y% m% d") / print "{:% Y% m% d}" .format ( aujourd'hui)
Format d'image en Python
[Python2] Chaîne de date → UnixTime → Chaîne de date
Notes sur le format Python Pickle
Utilisation méthodique du format [Python]
Génération de chaînes aléatoires (Python)
analyser pour le format, pour Jinja2 ...?
[Python] Fractionner la date
Python3> chaîne de documentation / docstring
Illustration de traitement de chaîne Python
Vérifiez si la chaîne est un nombre en python
Analyser une chaîne JSON écrite dans un fichier en Python
Découpez une partie de la chaîne à l'aide d'une tranche Python
python> datetime> De la chaîne de date (format ISO: 2015-12-09 12:40:08) au type datetime
J'ai essayé de résumer les opérations de chaîne de Python
python3 Mesurez la vitesse de traitement.
[python] Convertir la date en chaîne
Formatez facilement JSON avec Python
Découvrez la largeur apparente d'une chaîne en python
Vers la retraite de Python2
Supprimer les espaces pleine largeur avant et après la chaîne (python)
Méthodes d'objet chaîne en Python
Trouver des erreurs en Python
[Python] Utiliser une séquence de chaînes
Comparons les types de tableaux Python
À propos du module Python venv
Obtenez le type MIME en Python et déterminez le format de fichier
À propos de la fonction enumerate (python)
[Python] Ajustement de la barre de couleurs
[Python] Récupérez le mois précédent