HOWTO · Python
Convertir une chaîne en booléen en Python
Convertissez une chaîne en booléen en Python avec bool(), des règles explicites vrai/faux, des compréhensions de liste, map(), strtobool() et json.loads(), et découvrez pourquoi bool("False") renvoie True et pourquoi eval() est dangereux.
Sur cette page
Le texte provenant de fichiers, de configurations, de variables d’environnement ou de saisies utilisateur écrit les valeurs booléennes sous forme de chaînes telles que "true" et "false", et la reconversion de ce texte en un vrai True ou False dépend de la situation dans laquelle vous vous trouvez. Parfois, vous n’avez besoin que de la véracité (truthiness) — savoir si un texte est présent. Parfois, le texte provient d’un ensemble fixe de jetons que vous pouvez énumérer à l’avance. Parfois, le texte est un littéral JSON avec son orthographe stricte propre. Choisir la mauvaise conversion est une source classique de bogues, car l’outil le plus évident, bool(), ne lit jamais le texte : bool("False") renvoie True.
Ce tutoriel parcourt les méthodes de conversion dans cet ordre : bool() pour la véracité, des règles explicites pour les jetons connus, les mêmes règles appliquées à des listes avec une compréhension ou map(), l’ancien strtobool() avec ses limites exactes de disponibilité et de valeur de retour, json.loads() pour le texte JSON, et un avertissement final sur eval().
Convertir une chaîne en booléen avec bool()
La fonction bool() applique les règles de véracité de Python à la chaîne. Toute chaîne non vide vaut True, et la chaîne vide vaut False. Le contenu de la chaîne ne joue aucun rôle :
print(bool("False"))
print(bool("True"))
print(bool(""))
print(bool("hello"))
Production:
True
True
False
True
Utilisez bool() uniquement lorsque la question est celle de la présence — par exemple, si un paramètre facultatif a été fourni ou non. Dès que le texte lui-même porte le sens, comme le fait "False" ci-dessus, bool() donne silencieusement la mauvaise réponse et il vous faut à la place des règles explicites.
Convertir des valeurs textuelles connues avec des règles explicites
Lorsque vous savez quels jetons votre entrée peut contenir, comparez le texte à exactement ces jetons. Normalisez d’abord la casse et les espaces environnants, et levez une erreur pour tout ce qui n’est pas reconnu au lieu de deviner, de sorte qu’une faute de frappe dans un fichier de configuration apparaisse immédiatement au lieu de devenir silencieusement False :
def parse_bool(value):
text = value.strip().lower()
if text in ("true", "yes", "on", "1"):
return True
if text in ("false", "no", "off", "0"):
return False
raise ValueError(f"unrecognized boolean string: {value!r}")
print(parse_bool("True"))
print(parse_bool(" off "))
print(parse_bool("YES"))
Production:
True
False
True
Une entrée hors des ensembles acceptés lève l’erreur, que l’appelant peut intercepter et signaler :
try:
parse_bool("maybe")
except ValueError as error:
print(error)
Production:
unrecognized boolean string: 'maybe'
Ajustez les deux ensembles de jetons à votre source de données : un export CSV peut ne contenir que "true" et "false", tandis qu’un indicateur de ligne de commande peut aussi autoriser "on" et "off". C’est le fait que les ensembles soient explicites qui rend cette approche plus sûre que bool().
Convertir une liste de chaînes avec une compréhension de liste
Une comparaison produit déjà un booléen, donc une compréhension de liste convertit une liste entière en appliquant la comparaison à chaque élément. C’est la descendante directe de l’exemple de la version originale de ce tutoriel, avec les mêmes données :
words = ["False", "True", "False", "False", "True"]
flags = [word == "True" for word in words]
print(flags)
Production:
[False, True, False, False, True]
Lorsque la liste peut contenir plusieurs orthographes de jetons, réutilisez le convertisseur explicite de la section précédente au lieu d’une seule comparaison :
flags = [parse_bool(word) for word in ["true", "False", "yes", "off"]]
print(flags)
Production:
[True, False, True, False]
Avec parse_bool, un élément non reconnu lève ValueError et identifie la mauvaise valeur, au lieu d’aboutir silencieusement dans le résultat sous la forme False.
Utiliser map() comme alternative pour la conversion de listes
map() applique une fonction à chaque élément d’un itérable, donc elle effectue la même conversion lorsque vous lui passez une fonction à un argument. Avec une lambda, elle reflète la compréhension :
words = ["False", "True", "False", "False", "True"]
flags = list(map(lambda word: word == "True", words))
print(flags)
Production:
[False, True, False, False, True]
Le résultat est identique à la compréhension de liste. Préférez la compréhension lorsque la conversion est écrite en ligne, comme ici ; map() se lit mieux lorsque le convertisseur existe déjà comme fonction nommée, comme dans list(map(parse_bool, words)), qui applique les règles explicites à chaque élément sans lambda.
Traiter strtobool() comme une option héritée ou spécifique à une dépendance
Le code ancien utilise souvent strtobool() du module distutils.util de la bibliothèque standard. Ses limites sont précises, et elles comptent avant que vous ne vous y fiiez. La fonction faisait partie de la bibliothèque standard jusqu’à Python 3.11 inclus ; distutils a été déprécié en Python 3.10 par la PEP 632 et supprimé en Python 3.12, donc sur un interpréteur actuel, l’import échoue à moins que setuptools ne fournisse sa propre copie (voir ci-dessous). La documentation de Python 3.11 définit le comportement exactement : l’entrée est mise en minuscules, les valeurs vraies sont 'y', 'yes', 't', 'true', 'on' et '1', les valeurs fausses sont 'n', 'no', 'f', 'false', 'off' et '0', et toute autre valeur lève ValueError. La version de la bibliothèque standard renvoie les entiers 1 et 0, et non des booléens, donc enveloppez le résultat avec bool() lorsque vous avez besoin d’un vrai booléen :
from distutils.util import strtobool
print(strtobool("Yes"))
print(bool(strtobool("Yes")))
print(strtobool("off"))
Production:
1
True
0
La fonction survit également comme copie intégrée (vendored) dans setuptools, dont dépendent déjà de nombreux projets. Elle accepte les mêmes valeurs et lève la même ValueError (par exemple, invalid truth value 'abc'), mais les versions actuelles de setuptools renvoient directement True et False — vérifié avec setuptools 84.2.1 :
from setuptools._distutils.util import strtobool
print(strtobool("Yes"))
Production:
True
Parce que le type de retour et même l’origine du module diffèrent entre la copie de la bibliothèque standard, la copie de setuptools et le shim distutils que setuptools installe lorsqu’il est présent, traitez strtobool() comme une option héritée ou spécifique à une dépendance : acceptable lors de la maintenance de code qui l’utilise déjà sur un environnement d’exécution borné, mais pour du code nouveau, la fonction à règles explicites ci-dessus n’a aucune dépendance et se comporte de manière identique sur chaque version de Python.
Analyser les littéraux booléens JSON avec json.loads()
Lorsque la chaîne provient de données JSON, laissez l’analyseur JSON la convertir. JSON n’écrit ses littéraux booléens qu’en minuscules, et json.loads() renvoie de vrais booléens pour eux :
import json
print(json.loads("true"))
print(json.loads("false"))
Production:
True
False
La capitalisation à la Python n’est pas du JSON valide, donc le même appel avec "True" échoue au lieu de convertir :
import json
json.loads("True")
Production:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Gardez à l’esprit que json.loads() analyse n’importe quelle valeur JSON, pas seulement les booléens ; si l’entrée n’est pas fiable, vérifiez que le résultat est réellement un booléen avant de l’utiliser comme tel.
Pourquoi eval() est dangereux pour la conversion de chaînes
eval() semble convertir les chaînes, parce qu’il évalue la chaîne comme une expression Python et que True et False sont des expressions valides :
print(eval("False"))
Production:
False
C’est exactement le problème : eval() ne convertit pas la chaîne, il l’exécute. Une valeur telle que "__import__('os').getcwd()" n’est pas rejetée — elle est exécutée avec les permissions de votre programme, et une valeur hostile peut exécuter n’importe quoi. Ne passez jamais à eval() de texte provenant de fichiers, de réseaux ou d’utilisateurs. Si vos chaînes sont garanties être les littéraux Python "True" et "False", ast.literal_eval() les analyse sans rien exécuter, et refuse les expressions :
import ast
print(ast.literal_eval("True"))
print(ast.literal_eval("False"))
try:
ast.literal_eval("__import__('os').getcwd()")
except ValueError:
print("ValueError")
Production:
True
False
ValueError
En pratique, utilisez les règles explicites pour le texte de jetons, json.loads() pour le texte JSON, et ast.literal_eval() uniquement pour du texte garanti être un littéral Python — et laissez eval() entièrement en dehors du code de conversion.