Conversion d'une chaîne en booléen en Python?


746

Quelqu'un sait-il comment convertir une chaîne en un booléen en Python? J'ai trouvé ce lien . Mais cela ne semble pas être une bonne façon de procéder. C'est-à-dire en utilisant des fonctionnalités intégrées, etc.

La raison pour laquelle je pose cette question, c'est parce que j'ai appris int("string")d'ici. Mais en essayant, bool("string")il revient toujours True:

>>> bool("False")
True

2
J'ai créé une micro-bibliothèque juste pour cela, qui comprenait également quelques mots étrangers, par exemple "tak" pour le polonais, "'是 的" en chinois mandarin sera évalué à True . Si ce n'est pas explicitement true-ish sera évalué à False . Les suggestions sont les bienvenues. Lien Github: github.com/kmonsoor/str2bool
kmonsoor

18
Plutôt que de réinventer la roue et d'écrire un tas de code que vous devez cultiver, la réponse de @ jzwiener utilise une fonction de la bibliothèque standard de pythondistutils.util.strtobool(some_string) . Techniquement, la sortie est de type intavec valeur 0ou 1-> si vous voulez vraiment / besoin, boolvous pouvez envelopper cette fonction avec bool(distutils.util.strtobool(some_string)).
Trevor Boyd Smith

1
pip install str2bool
Symon

Juste un avertissement. distutils.util.strtoboolne peut pas gérer les oui / non étrangers, contrairement à la solution de @kmonsoor, qui ne peut cependant pas gérer les fichiers CSV créés par Excel avec True / False dans une langue étrangère (par exemple VERO, FALSO). La réinvention des roues est donc parfois nécessaire.
Matteo Ferla

Réponses:


838

Vraiment, vous comparez simplement la chaîne à tout ce que vous pensez accepter comme représentant vrai, vous pouvez donc faire ceci:

s == 'True'

Ou pour vérifier par rapport à tout un tas de valeurs:

s.lower() in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh']

Soyez prudent lorsque vous utilisez les éléments suivants:

>>> bool("foo")
True
>>> bool("")
False

Les chaînes vides sont évaluées à False, mais tout le reste est évalué à True. Donc, cela ne doit pas être utilisé à des fins d'analyse.


48
+1: Pas grand-chose de plus simple que s == "True". Mais j'ai vu des gens en faire un vrai bordel. conversion (s) par défaut: if s == "True": return True; retourne faux.
S.Lott

24
Je préfère le retour s == "True" plutôt que le if / else
Dana

26
if s == "True": return True elif s == "False": return False else: return raise
Unknown

9
L'analyse des chaînes en booléens est déjà implémentée dans distutils.util.strtobool: stackoverflow.com/a/18472142/923599
jzwiener

9
Je sais que c'est un sujet VRAIMENT ancien, mais je voulais attester que je viens de passer 4 heures à essayer de déboguer mon code. Mon erreur était d'essayer de lancer bool("False"). Il sera toujours jeté sur True.
Ev.

304

Utilisation:

bool(distutils.util.strtobool(some_string))

Les vraies valeurs sont y, oui, t, true, on et 1; les fausses valeurs sont n, non, f, faux, désactivé et 0. Déclenche ValueError si val est autre chose.

Sachez que distutils.util.strtobool()renvoie des représentations entières et qu'il doit donc être encapsulé bool()pour obtenir des valeurs booléennes.


38
Malheureusement, cela renvoie 1/ 0non True/ False, vous devez donc envelopper le résultat dans bool () pour obtenir un booléen réel:bool(distutils.util.strtobool(some_string))
Mariusz Jamro

2
Cette fonction est alléchante. Ce serait parfait s'il traitait des entiers et Noneet str(None)en entrée.
MarkHu

20
Je préfère de beaucoup cela aux réponses plus votées ... c'est de stdlib et fait exactement ce qui est requis. Il n'y a généralement aucune raison d'avoir besoin d'un réel boolau lieu de 1/ 0tant que vous ne faites pas de mauvaises choses comme if x == False... et si vous traitez avec ints et Nones vous n'avez pas besoin d'une fonction spéciale, vous pouvez simplement les vérifier directement if myint:ouif not maybe_none_var:
Anentropic

4
@Secator boolest une sous-classe deint
Anentropic

2
Pour sauver quelqu'un des erreurs de recherche sur Google: importez distutils et importez distutils.util pour que cela fonctionne.
Edward B.

267
def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")

Appelez-le ainsi:

>>> str2bool("yes")
True
>>> str2bool("no")
False
>>> str2bool("stuff")
False
>>> str2bool("1")
True
>>> str2bool("0")
False

Gérer explicitement le vrai et le faux:

Vous pouvez également faire en sorte que votre fonction vérifie explicitement une vraie liste de mots et une fausse liste de mots. Si elle ne figure dans aucune des deux listes, vous pouvez lever une exception.


29
peu d'améliorations peuvent être apportées en utilisant, str (v) .lower () au lieu de v.lower () . Ensuite, cela peut fonctionner même si ce n'est pas une chaîne, par exemple 1, 0
kmonsoor

RE: en gérant explicitement true / false, vous pouvez également fournir une valeur par défaut si la chaîne ne correspond pas, tout comme le fonctionnement des invites de ligne de commande true / false: Continuer? (
o

114

L'analyseur JSON est également utile pour en général convertir des chaînes en types python raisonnables.

>>> import json
>>> json.loads("false".lower())
False
>>> json.loads("True".lower())
True

31
Notez que cette méthode ne fonctionne que si elle est en minuscules. Si c'est en majuscule, vous ne pouvez pas. Vous devez appeler.lower()
CppLearner

107

Depuis Python 2.6, il y a maintenant ast.literal_eval:

>>> importer ast
>>> aide (ast.literal_eval)
Aide sur la fonction literal_eval dans le module ast:

literal_eval (node_or_string)
    Évaluez en toute sécurité un nœud d'expression ou une chaîne contenant un Python
    expression. La chaîne ou le nœud fourni ne peut comprendre que les éléments suivants
    Structures littérales Python: chaînes, nombres, tuples, listes, dict, booléens,
    et aucun.

Ce qui semble fonctionner, tant que vous êtes sûr que vos cordes seront soit "True"ou "False":

>>> ast.literal_eval ("True")
Vrai
>>> ast.literal_eval ("False")
Faux
>>> ast.literal_eval ("F")
Traceback (dernier appel le plus récent):
  Fichier "", ligne 1, dans 
  Fichier "/opt/Python-2.6.1/lib/python2.6/ast.py", ligne 68, dans literal_eval
    return _convert (node_or_string)
  Fichier "/opt/Python-2.6.1/lib/python2.6/ast.py", ligne 67, dans _convert
    augmenter ValueError ('chaîne mal formée')
ValueError: chaîne mal formée
>>> ast.literal_eval ("'False'")
'Faux'

Je ne recommanderais normalement pas cela, mais il est entièrement intégré et pourrait être la bonne chose en fonction de vos besoins.


1
Je ne suis pas sûr de l'applicabilité générale de cette solution, mais c'est très agréable, d'une manière générale. +1!
SingleNegationElimination

3
Gaah, c'est horrible! Là encore, vous avez dit que vous ne le recommande pas, et il ne répondre à la question d'une manière ordonnée. Bonne trouvaille!
Vanessa Phipps

4
Malheureusement, il ne gère pas ce cas >>> ast.literal_eval ('true') ou ast.literal_eval ('TRUE') Augmente >>> raise ValueError ('malformed string') Le correctif est simple mais ast.literal_eval (to_test .title ())
Bhushan

Pas une excellente solution à cette question particulière, mais ... Wow, literal_eval est sacrément utile! Chaîne à lister, dicter, ect.
travc

Fonctionne-t-il sur les unicodes? Dans ma vue Django, j'ai une valeur entrante que je veux changer en booléen, cela donne une exception de chaîne mal formée.
Prakhar Mohan Srivastava

48

Si vous savez que la chaîne sera soit "True"ou "False", vous pouvez simplement utiliser eval(s).

>>> eval("True")
True
>>> eval("False")
False

N'utilisez cela que si vous êtes sûr du contenu de la chaîne, car il lèvera une exception si la chaîne ne contient pas de Python valide et exécutera également le code contenu dans la chaîne.


5
cette chaîne viendra de quelque part. if eval(os.environ["LOL"]): #might never reach here. Might also charge your company's credit card.
nurettin

4
@nurettin, d'où mon commentaire de ne l'utiliser que si vous êtes sûr du contenu de la chaîne.
Joel Croteau

17

Cette version conserve la sémantique des constructeurs comme int (valeur) et fournit un moyen simple de définir des valeurs de chaîne acceptables.

def to_bool(value):
    valid = {'true': True, 't': True, '1': True,
             'false': False, 'f': False, '0': False,
             }   

    if isinstance(value, bool):
        return value

    if not isinstance(value, basestring):
        raise ValueError('invalid literal for boolean. Not a string.')

    lower_value = value.lower()
    if lower_value in valid:
        return valid[lower_value]
    else:
        raise ValueError('invalid literal for boolean: "%s"' % value)


# Test cases
assert to_bool('true'), '"true" is True' 
assert to_bool('True'), '"True" is True' 
assert to_bool('TRue'), '"TRue" is True' 
assert to_bool('TRUE'), '"TRUE" is True' 
assert to_bool('T'), '"T" is True' 
assert to_bool('t'), '"t" is True' 
assert to_bool('1'), '"1" is True' 
assert to_bool(True), 'True is True' 
assert to_bool(u'true'), 'unicode "true" is True'

assert to_bool('false') is False, '"false" is False' 
assert to_bool('False') is False, '"False" is False' 
assert to_bool('FAlse') is False, '"FAlse" is False' 
assert to_bool('FALSE') is False, '"FALSE" is False' 
assert to_bool('F') is False, '"F" is False' 
assert to_bool('f') is False, '"f" is False' 
assert to_bool('0') is False, '"0" is False' 
assert to_bool(False) is False, 'False is False'
assert to_bool(u'false') is False, 'unicode "false" is False'

# Expect ValueError to be raised for invalid parameter...
try:
    to_bool('')
    to_bool(12)
    to_bool([])
    to_bool('yes')
    to_bool('FOObar')
except ValueError, e:
    pass

3
Nit: Votre dernier "cas de test" sera erroné lors du premier appel et ne testera pas les autres. De plus, il n'échouera pas si aucune erreur n'est signalée.
août

12

Voici ma version. Il vérifie les listes de valeurs positives et négatives, levant une exception pour les valeurs inconnues. Et il ne reçoit pas de chaîne, mais tout type devrait le faire.

def to_bool(value):
    """
       Converts 'something' to boolean. Raises exception for invalid formats
           Possible True  values: 1, True, "1", "TRue", "yes", "y", "t"
           Possible False values: 0, False, None, [], {}, "", "0", "faLse", "no", "n", "f", 0.0, ...
    """
    if str(value).lower() in ("yes", "y", "true",  "t", "1"): return True
    if str(value).lower() in ("no",  "n", "false", "f", "0", "0.0", "", "none", "[]", "{}"): return False
    raise Exception('Invalid value for boolean conversion: ' + str(value))

Exemples de cycles:

>>> to_bool(True)
True
>>> to_bool("tRUe")
True
>>> to_bool("1")
True
>>> to_bool(1)
True
>>> to_bool(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: 2
>>> to_bool([])
False
>>> to_bool({})
False
>>> to_bool(None)
False
>>> to_bool("Wasssaaaaa")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: Wasssaaaaa
>>>

On pourrait se faire mordre par ceci: ce to_bool(["hello"])qui devrait être un appel parfaitement valide, s'il []est pris en charge
Rafael T

1
Renvoie "Exception: valeur non valide pour la conversion booléenne: ['bonjour']", qui est attendue et documentée. À mon avis, une liste vide était clairement une fausse, mais ['false'] n'était clairement rien, alors je l'ai laissée intentionnellement - c'est une fonctionnalité pas un bug. Cela devrait être facile d'ajouter la prise en charge du retour vrai pour les listes non vides si c'est ce que vous voulez.
Petrucio

1
Assurez-vous de l'avoir documenté. Mais en vrai, on n'appellerait jamais to_bool([]). Au lieu de cela, il ferait quelque chose dans ce sens: myList=someFunctionThatReturnAList`if (is_bool (myList)): ... ´ donc on a une liste et on veut savoir si cette liste est None ou vide.
Rafael T

Pourquoi ne pas essayer ceci: >>> def a2b (arg): ... default = bool (arg) ... if isinstance (arg, str): ... return arg.lower () in ['true', ' t ',' yes ',' y ',' 1 '] ... else: ... return default
ThePracticalOne

5
Point mineur: vous devriez probablement préférer ValueError à une simple exception.
dshepherd

10

vous pourriez toujours faire quelque chose comme

myString = "false"
val = (myString == "true")

le bit en parens serait évalué à faux. C'est juste une autre façon de le faire sans avoir à faire un véritable appel de fonction.


1
Que fait la val = "false"ligne sur cet exemple? Pourquoi est-il là? Qu'est-ce que ça veut dire?
S.Lott

9
Je pense que cela signifie 42.
Geo

@Geo: je suis d'accord; mais quelle était la question à laquelle répond cette déclaration?
S.Lott

c'est exactement ce que je cherchais, en évaluant un champ d'entrée à partir d'un fichier et en fonction du résultat stockant un booléen. Merci.
Jimh

9

Un truc cool et simple (basé sur ce que @Alan Marchiori a publié), mais en utilisant yaml:

import yaml

parsed = yaml.load("true")
print bool(parsed)

S'il est trop large, il peut être affiné en testant le résultat du type. Si le type renvoyé par yaml est une chaîne, il ne peut pas être converti en un autre type (auquel je peux penser de toute façon), vous pouvez donc le gérer séparément, ou simplement le laisser être vrai.

Je ne ferai aucune supposition à la vitesse, mais puisque je travaille avec des données yaml sous Qt gui de toute façon, cela a une symétrie sympa.


1
Le yamlmodule est une bibliothèque tierce: PyYAML
Peter Wood

8

Je ne suis d'accord avec aucune solution ici, car elles sont trop permissives. Ce n'est normalement pas ce que vous voulez lors de l'analyse d'une chaîne.

Voici donc la solution que j'utilise:

def to_bool(bool_str):
    """Parse the string and return the boolean value encoded or raise an exception"""
    if isinstance(bool_str, basestring) and bool_str: 
        if bool_str.lower() in ['true', 't', '1']: return True
        elif bool_str.lower() in ['false', 'f', '0']: return False

    #if here we couldn't parse it
    raise ValueError("%s is no recognized as a boolean value" % bool_str)

Et les résultats:

>>> [to_bool(v) for v in ['true','t','1','F','FALSE','0']]
[True, True, True, False, False, False]
>>> to_bool("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in to_bool
ValueError: '' is no recognized as a boolean value

Juste pour être clair, car il semble que ma réponse ait offensé quelqu'un:

Le fait est que vous ne voulez pas tester une seule valeur et supposer l'autre. Je ne pense pas que vous souhaitiez toujours mapper absolument tout à la valeur non analysée. Cela produit un code sujet aux erreurs.

Donc, si vous savez dans quoi vous voulez le coder.


2
Je pense que vous manquez le point: le but des réponses était de démontrer le principe général, pas de dire à la personne qui a posé la question exactement comment elle devrait le faire. La personne qui a posé la question à l'origine pensait trop à ce qui est réellement un problème simple.
Keith Gaughan

8
@Keith, je ne suis pas d'accord. Il s'agit de répondre à la question telle qu'elle est posée.
estani

1
La question posée était de savoir comment convertir une chaîne en booléen. Voilà la question à laquelle j'ai répondu. Je n'ai aucune idée de ce qui est considéré comme une chaîne booléenne valide pour l'affiche originale, et vous non plus. C'est pourquoi il est plus important de démontrer le principe général que de donner à l'affiche la réponse complète. L'affiche originale n'avait pas besoin que tout leur soit expliqué: tout ce dont ils avaient besoin était de démontrer le principe général. De là, toute personne compétente obtiendra votre réponse.
Keith Gaughan

2
@dshepherd l'instance est là pour être sûr que j'analyse ce que j'attends. Je suis en train d'analyser des chaînes, donc une méthode car_race.lower () qui, par hasard, retourne '1' ne devrait pas retourner vrai, elle devrait lancer une ValueError. Mais cela pourrait suffire dans d'autres cas.
estani

2
@CivFan point intéressant. Même si je l'ai essayé, et il ne s'est pas lu si bien (pour moi). elifest redondant à cause du mot de retour, mais il vous donne plus d'informations sans avoir à rechercher return. Mais ce n'est que moi, s'il y a une violation de style PEP, je le changerais cependant. Sans aucune autre contrainte, nous devrions toujours opter pour la lisibilité (et les normes le font). Merci pour la tête et commentaire intéressant!
estani

7

Un dict (vraiment, un defaultdict) vous donne un moyen assez simple de faire cette astuce:

from collections import defaultdict
bool_mapping = defaultdict(bool) # Will give you False for non-found values
for val in ['True', 'yes', ...]:
    bool_mapping[val] = True

print(bool_mapping['True']) # True
print(bool_mapping['kitten']) # False

Il est très facile d'adapter cette méthode au comportement de conversion exact que vous souhaitez - vous pouvez la remplir avec les valeurs Truthy et Falsy autorisées et la laisser lever une exception (ou renvoyer None) lorsqu'une valeur n'est pas trouvée, ou par défaut True, ou par défaut False, ou tout ce que vous voulez.


5

Vous avez probablement déjà une solution, mais pour ceux qui recherchent une méthode pour convertir une valeur en valeur booléenne à l'aide de fausses valeurs "standard", notamment None, [], {} et "" en plus de false, no et 0 .

def toBoolean( val ):
    """ 
    Get the boolean value of the provided input.

        If the value is a boolean return the value.
        Otherwise check to see if the value is in 
        ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]
        and returns True if value is not in the list
    """

    if val is True or val is False:
        return val

    falseItems = ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]

    return not str( val ).strip().lower() in falseItems

1
il vaut mieux utiliser des ensembles, not inet votre sélection de faux éléments est quelque peu idiosyncrasique.
SilentGhost

5

Vous pouvez simplement utiliser la fonction intégrée eval () :

a='True'
if a is True:
    print 'a is True, a type is', type(a)
else:
    print "a isn't True, a type is", type(a)
b = eval(a)
if b is True:
    print 'b is True, b type is', type(b)
else:
    print "b isn't True, b type is", type(b)

et la sortie:

a isn't True, a type is <type 'str'>
b is True, b type is <type 'bool'>

1
Cela ne fonctionne que lorsque les valeurs testées sont en python valide. "true" et "false" lèveront une exception.
Gordon Bean

13
De plus, c'est une très mauvaise habitude d'utiliser 'eval' pour l'analyse car eval exécutera du code arbitraire dans la chaîne. Dans certaines situations, cela peut présenter un énorme ensemble de sécurité.
Christopher Barber

7
C'est une très mauvaise réponse. Évaluer une expression arbitraire pour analyser un booléen n'est PAS une bonne approche.
août

5

Encore une autre option

from ansible.module_utils.parsing.convert_bool import boolean
boolean('no')
# False
boolean('yEs')
# True
boolean('true')
# True

Mais en production, si vous n'avez pas besoin de ansible et de toutes ses dépendances, une bonne idée est de regarder son code source et de copier une partie de la logique dont vous avez besoin.


4

La règle habituelle pour la coulée à un bool est que quelques littéraux spéciaux ( False, 0, 0.0, (), [], {}) sont faux et tout le reste est vrai, donc je recommande ce qui suit:

def boolify(val):
    if (isinstance(val, basestring) and bool(val)):
        return not val in ('False', '0', '0.0')
    else:
        return bool(val)

3

Ceci est la version que j'ai écrite. Combine plusieurs des autres solutions en une seule.

def to_bool(value):
    """
    Converts 'something' to boolean. Raises exception if it gets a string it doesn't handle.
    Case is ignored for strings. These string values are handled:
      True: 'True', "1", "TRue", "yes", "y", "t"
      False: "", "0", "faLse", "no", "n", "f"
    Non-string values are passed to bool.
    """
    if type(value) == type(''):
        if value.lower() in ("yes", "y", "true",  "t", "1"):
            return True
        if value.lower() in ("no",  "n", "false", "f", "0", ""):
            return False
        raise Exception('Invalid value for boolean conversion: ' + value)
    return bool(value)

S'il obtient une chaîne, il attend des valeurs spécifiques, sinon déclenche une exception. S'il n'obtient pas de chaîne, laisse simplement le constructeur bool le comprendre. Testé ces cas:

test_cases = [
    ('true', True),
    ('t', True),
    ('yes', True),
    ('y', True),
    ('1', True),
    ('false', False),
    ('f', False),
    ('no', False),
    ('n', False),
    ('0', False),
    ('', False),
    (1, True),
    (0, False),
    (1.0, True),
    (0.0, False),
    ([], False),
    ({}, False),
    ((), False),
    ([1], True),
    ({1:2}, True),
    ((1,), True),
    (None, False),
    (object(), True),
    ]

Utiliser strau lieu detype('')
pppery

3

Si vous savez que votre entrée sera "vraie" ou "fausse", alors pourquoi ne pas utiliser:

def bool_convert(s):
    return s == "True"

En fait, vous n'en avez pas besoin if s else False. Réfléchissez à la façon dont "False" == "True"reviendra déjà False.
Taylor Edmiston

Si vous ne savez pas si l'entrée s est une chaîne ou déjà un booléen, vous pouvez ajouter if type(s) is bool: return s.
kontur

3

j'utilise

# function
def toBool(x):
    return x in ("True","true",True)

# test cases
[[x, toBool(x)] for x in [True,"True","true",False,"False","false",None,1,0,-1,123]]
"""
Result:
[[True, True],
 ['True', True],
 ['true', True],
 [False, False],
 ['False', False],
 ['false', False],
 [None, False],
 [1, True],
 [0, False],
 [-1, False],
 [123, False]]
"""

2

J'aime utiliser l'opérateur ternaire pour cela, car c'est un peu plus succinct pour quelque chose qui semble ne pas dépasser 1 ligne.

True if myString=="True" else False

1
En quoi est-il plus succinct que my_string == 'True'?
S. de Melo

2

Je me rends compte que c'est un vieux post, mais certaines des solutions nécessitent pas mal de code, voici ce que j'ai fini par utiliser:

def str2bool(value):
    return {"True": True, "true": True}.get(value, False)

7
C'est fonctionnellement équivalent à, et plus complexe que: valeur de retour dans ('True', 'true')
Keith Gaughan


1

Si vous m'aimez juste besoin d'un booléen à partir d'une variable qui est une chaîne. Vous pouvez utiliser des distils comme mentionné précédemment par @jzwiener. Cependant, je n'ai pas pu importer et utiliser le module comme il l'a suggéré.

Au lieu de cela, je finis par l'utiliser de cette façon sur python3.7

chaîne distutils à bool en python

from distutils import util # to handle str to bool conversion
enable_deletion = 'False'
enable_deletion = bool(util.strtobool(enable_deletion))

distutils fait partie de la bibliothèque python std donc pas besoin d'installation. Qui est super! 👍


1

Je voudrais partager ma solution simple: utilisez le eval(). Il convertira la chaîne Trueet Falsele type booléen approprié SI la chaîne est exactement au format du titre Trueou Falsetoujours en majuscule, sinon la fonction déclenchera une erreur.

par exemple

>>> eval('False')
False

>>> eval('True')
True

Bien sûr, pour la variable dynamique, vous pouvez simplement utiliser le .title()pour formater la chaîne booléenne.

>>> x = 'true'
>>> eval(x.title())
True

Cela générera une erreur.

>>> eval('true')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'true' is not defined

>>> eval('false')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'false' is not defined

0

voici un moyen poilu, construit pour obtenir plusieurs des mêmes réponses. Notez que bien que python considère ""comme faux et que toutes les autres chaînes soient vraies, TCL a une idée très différente des choses.

>>> import Tkinter
>>> tk = Tkinter.Tk()
>>> var = Tkinter.BooleanVar(tk)
>>> var.set("false")
>>> var.get()
False
>>> var.set("1")
>>> var.get()
True
>>> var.set("[exec 'rm -r /']")
>>> var.get()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 324, in get
    return self._tk.getboolean(self._tk.globalgetvar(self._name))
_tkinter.TclError: 0expected boolean value but got "[exec 'rm -r /']"
>>> 

Une bonne chose à ce sujet est qu'il pardonne assez les valeurs que vous pouvez utiliser. Il est paresseux de transformer des chaînes en valeurs, et il est hygiénique de ce qu'il accepte et rejette (notez que si l'instruction ci-dessus était donnée à l'invite tcl, cela effacerait le disque dur de l'utilisateur).

la mauvaise chose est qu'elle nécessite que Tkinter soit disponible, ce qui est généralement, mais pas universellement vrai, et plus important encore, nécessite la création d'une instance Tk, ce qui est relativement lourd.

Ce qui est considéré comme vrai ou faux dépend du comportement du Tcl_GetBoolean, qui considère 0, false, noet offd'être faux et 1, true, yeset onpour être vrai, insensible à la casse. Toute autre chaîne, y compris la chaîne vide, provoque une exception.


0
def str2bool(str):
  if isinstance(str, basestring) and str.lower() in ['0','false','no']:
    return False
  else:
    return bool(str)

idée: vérifiez si vous voulez que la chaîne soit évaluée à False; sinon bool () renvoie True pour toute chaîne non vide.


0

Voici quelque chose que j'ai jeté ensemble pour évaluer la véracité d'une chaîne:

def as_bool(val):
 if val:
  try:
   if not int(val): val=False
  except: pass
  try:
   if val.lower()=="false": val=False
  except: pass
 return bool(val)

plus ou moins les mêmes résultats que l'utilisation, evalmais plus sûr.


0

Je devais juste faire ça ... alors peut-être en retard à la fête - mais quelqu'un peut le trouver utile

def str_to_bool(input, default):
    """
    | Default | not_default_str | input   | result
    | T       |  "false"        | "true"  |  T
    | T       |  "false"        | "false" |  F
    | F       |  "true"         | "true"  |  T
    | F       |  "true"         | "false" |  F

    """
    if default:
        not_default_str = "false"
    else:
        not_default_str = "true"

    if input.lower() == not_default_str:
        return not default
    else:
        return default

0

Si vous avez le contrôle sur l'entité qui retourne true/ false, une option est de la faire retourner 1/ 0au lieu de true/ false, alors:

boolean_response = bool(int(response))

Le cast supplémentaire intgère les réponses d'un réseau, qui sont toujours des chaînes.


-5

En utilisant la fonction intégrée de Python eval()et le.capitalize() méthode de , vous pouvez convertir n'importe quelle chaîne "vraie" / "fausse" (quelle que soit la capitalisation initiale) en un vrai booléen Python.

Par exemple:

true_false = "trUE"
type(true_false)

# OUTPUT: <type 'str'>

true_false = eval(true_false.capitalize())
type(true_false)

# OUTPUT: <type 'bool'>

4
Que se passe-t-il si la chaîne contient #\nshutil.rmtree('/someImportantDirectory')? (N'essayez pas!)
Mastov

@mastov - downvote ridicule. Évidemment, si vous ne contrôlez pas la chaîne entrante, vous devez mettre en place des précautions, comme vous le feriez avec n'importe quel code. Mais si vous contrôlez le workflow, il s'agit d'une solution simple qui fonctionne. Ne confondez pas une solution qui n'est pas parfaite à tous égards avec une mauvaise réponse.
elPastor

1
En plus de ne pas mentionner les dangers (ce qui en fait déjà une mauvaise réponse): vous proposez de désinfecter l'entrée au préalable? Cela va tuer la simplicité de cette méthode, qui était son principal avantage.
mastov

4
Utiliser evalquelque chose d'aussi simple demande simplement une vulnérabilité.
mastov

1
Pas tout le code. Mais en particulier, le code qui convertit les chaînes en d'autres types est généralement hors de votre contrôle. Souvent, vous pourriez même ne pas vous en rendre compte. Vous pourriez dire: "C'est ma base de données (ou fichier de configuration), elle fait partie de mon système, sous mon contrôle." Ensuite, vous donnez à un autre module l'accès à une base de données parce que: "Quel est le mal? Ce ne sont que quelques tables avec des chaînes." Mais avec evalces chaînes pourrait aider quelqu'un à prendre en charge l'ensemble du système.
mastov
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.