¿Convertir de una cadena a booleana en Python?

746

¿Alguien sabe cómo convertir de una cadena a un booleano en Python? Encontré este enlace . Pero no parece una forma adecuada de hacerlo. Es decir, utilizando la funcionalidad incorporada, etc.

La razón por la que pregunto esto es porque aprendí int("string")de aquí. Pero cuando lo intentas bool("string")siempre vuelve True:

>>> bool("False")
True
Joan Venge
fuente
2
he creado una microbiblioteca solo para esto que también incluía algunas palabras extranjeras, por ejemplo, "tak" para polaco, "'是 的" en chino mandarín se evaluará como verdadero . Si no es explícitamente true-ish se evaluará como False . Las sugerencias son bienvenidas. Enlace de Github: github.com/kmonsoor/str2bool
kmonsoor
18
En lugar de reinventar la rueda y escribir un montón de código que tiene que cargar con el culto de carga, la respuesta de @jzwiener utiliza una función de la biblioteca estándar de Pythondistutils.util.strtobool(some_string) . Técnicamente, la salida es tipo intcon valor 0o 1-> si realmente quiere / necesita, boolentonces puede ajustar esa función bool(distutils.util.strtobool(some_string)).
Trevor Boyd Smith
1
pip install str2bool
Symon
Solo un aviso. distutils.util.strtoboolno puede manejar el sí / no extranjero, a diferencia de la solución de @kmonsoor, que sin embargo no puede manejar los archivos CSV creados por Excel con Verdadero / Falso en un idioma extranjero (por ejemplo VERO, FALSO). Por lo tanto, a veces se requiere la reinvención de la rueda.
Matteo Ferla

Respuestas:

838

Realmente, solo compara la cadena con lo que espera aceptar como representación verdadera, para que pueda hacer esto:

s == 'True'

O para verificar contra un montón de valores:

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

Tenga cuidado al usar lo siguiente:

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

Las cadenas vacías se evalúan como False, pero todo lo demás se evalúa como True. Por lo tanto, esto no debe usarse para ningún tipo de análisis.

Keith Gaughan
fuente
48
+1: No mucho podría ser más simple que s == "True". Pero he visto a personas hacer un verdadero desastre con esto. def convert (s): if s == "True": devuelve True; falso retorno.
S.Lott 03 de
24
Prefiero devolver s == "True" sobre if / else
Dana el
26
if s == "True": return True elif s == "False": return False else: return raise
Desconocido
99
El análisis de cadenas a booleanos ya está implementado en distutils.util.strtobool: stackoverflow.com/a/18472142/923599
jzwiener
99
Sé que este es un tema REALMENTE antiguo, pero quería dar fe de que acabo de pasar 4 horas tratando de depurar mi código. Mi error fue intentar lanzar bool("False"). Siempre se lanzará a True.
Ev.
304

Utilizar:

bool(distutils.util.strtobool(some_string))

Los valores verdaderos son y, yes, t, true, on y 1; los valores falsos son n, no, f, falso, apagado y 0. Aumenta ValueError si val es otra cosa.

Tenga en cuenta que distutils.util.strtobool()devuelve representaciones enteras y, por lo tanto, debe envolverse bool()para obtener valores booleanos.

jzwiener
fuente
38
Desafortunadamente, esto devuelve 1/ 0no True/ False, por lo que debe ajustar el resultado en bool () para obtener un booleano real:bool(distutils.util.strtobool(some_string))
Mariusz Jamro
2
Esa función es tentadora. Sería perfecto si manejara enteros Noney str(None)como entrada.
MarkHu
20
Prefiero esto a las respuestas más votadas ... es de stdlib y hace exactamente lo que se requiere. Generalmente, no hay razón para necesitar un real boolen lugar de 1/ 0, siempre y cuando usted no está haciendo cosas malas como if x == False... y si usted está tratando con ints y NoneS que no es necesario una función especial, sólo puede comprobar a directamente if myint:oif not maybe_none_var:
Anentropic
44
@Secator booles una subclase deint
Anentropic
2
Para ahorrarle a alguien algunos errores en Google: importe distutils e import distutils.util para que esto funcione.
Edward B.
267
def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")

Entonces llámalo así:

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

Manejo de verdadero y falso explícitamente:

También puede hacer que su función verifique explícitamente una lista Verdadera de palabras y una Lista falsa de palabras. Entonces, si no está en ninguna de las dos listas, puede lanzar una excepción.

Brian R. Bondy
fuente
29
Se puede hacer una pequeña mejora usando str (v) .lower () en lugar de v.lower () . Entonces, puede funcionar incluso si no es una cadena, por ejemplo, 1, 0
kmonsoor
RE: manejo explícito verdadero / falso, también podría proporcionar un valor predeterminado si la cadena no coincide, al igual que cómo funcionan las indicaciones de línea de comando verdadero / falso: ¿Continuar? (s / N)
Johnus
114

El analizador JSON también es útil para, en general, convertir cadenas a tipos de python razonables.

>>> import json
>>> json.loads("false".lower())
False
>>> json.loads("True".lower())
True
Alan Marchiori
fuente
31
Tenga en cuenta que este método solo funciona si está en minúsculas. Si es mayúscula, no puedes. Tienes que llamar.lower()
CppLearner
107

Comenzando con Python 2.6, ahora hay ast.literal_eval:

>>> importar ast
>>> ayuda (ast.literal_eval)
Ayuda sobre la función literal_eval en el módulo ast:

literal_eval (nodo_o_cadena)
    Evalúe de forma segura un nodo de expresión o una cadena que contenga un Python
    expresión. La cadena o nodo proporcionado solo puede consistir en lo siguiente
    Estructuras literales de Python: cadenas, números, tuplas, listas, dictos, booleanos,
    y ninguno

Lo que parece funcionar, siempre y cuando esté seguro de que sus cadenas serán "True"o "False":

>>> ast.literal_eval ("Verdadero")
Cierto
>>> ast.literal_eval ("Falso")
Falso
>>> ast.literal_eval ("F")
Rastreo (llamadas recientes más última):
  Archivo "", línea 1, en 
  Archivo "/opt/Python-2.6.1/lib/python2.6/ast.py", línea 68, en literal_eval
    return _convert (nodo_o_cadena)
  Archivo "/opt/Python-2.6.1/lib/python2.6/ast.py", línea 67, en _convert
    raise ValueError ('cadena malformada')
ValueError: cadena con formato incorrecto
>>> ast.literal_eval ("'False'")
'Falso'

Normalmente no recomendaría esto, pero está completamente integrado y podría ser lo correcto dependiendo de sus requisitos.

Jacob Gabrielson
fuente
1
No estoy seguro de la aplicabilidad general de esta solución, pero es muy agradable, en general. +1!
SingleNegationElimination
3
Gaah, eso es horrible! Por otra parte, se hizo decir que no lo recomendamos, y lo hace responder a la pregunta cuidadosamente. ¡Buen descubrimiento!
Vanessa Phipps
44
Desafortunadamente no maneja este caso >>> ast.literal_eval ('true') o ast.literal_eval ('TRUE') Eleva >>> raise ValueError ('cadena malformada') La solución es simple aunque ast.literal_eval (to_test .title ())
Bhushan
No es una gran solución para esta pregunta en particular, pero ... ¡Wow, literal_eval es muy útil! Cadena para enumerar, dictar, ect.
travc
¿Funciona en Unicodes a? En mi vista de Django, tengo un valor entrante que quiero cambiar a booleano, está dando una excepción de cadena con formato incorrecto.
Prakhar Mohan Srivastava
48

Si sabe que la cadena será "True"o bien "False", puede usarla eval(s).

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

Sin embargo, solo use esto si está seguro del contenido de la cadena, ya que arrojará una excepción si la cadena no contiene Python válido y también ejecutará el código contenido en la cadena.

Joel Croteau
fuente
55
esa cuerda vendrá de alguna parte. if eval(os.environ["LOL"]): #might never reach here. Might also charge your company's credit card.
nurettin
44
@nurettin, de ahí mi comentario sobre solo usarlo si está seguro del contenido de la cadena.
Joel Croteau
17

Esta versión mantiene la semántica de constructores como int (value) y proporciona una manera fácil de definir valores de cadena aceptables.

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
Michael Richmond
fuente
3
Nit: Su último "caso de prueba" tendrá un error en la primera llamada y no probará las otras. Además, no se producirá un error si se produce un error no planteó.
augurar
12

Aquí está mi versión. Comprueba las listas de valores positivos y negativos, generando una excepción para valores desconocidos. Y no recibe una cadena, pero cualquier tipo debería hacerlo.

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))

Ejecuciones de muestra:

>>> 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
>>>
Petrucio
fuente
Uno podría ser mordido por esto: to_bool(["hello"])que debería ser una llamada perfectamente válida, si []es compatible
Rafael T
1
Devuelve "Excepción: valor no válido para la conversión booleana: ['hola']", que se espera y se documenta. En mi opinión, una lista vacía era claramente falsa, pero ['falso'] no era claramente nada, así que la omití intencionalmente; esa es una característica, no un error. Debería ser fácil agregar soporte para devolver verdadero para listas no vacías si eso es lo que desea.
Petrucio
1
Shure lo documentaste. Pero en la vida real uno nunca llamaría to_bool([]). En cambio, haría algo en este sentido: myList=someFunctionThatReturnAList`if (is_bool (myList)): ... ´ entonces uno tiene una lista y quiere saber si esta lista es None o está vacía.
Rafael T
¿Por qué no probar esto? >>> def a2b (arg): ... default = bool (arg) ... if isinstance (arg, str): ... return arg.lower () en ['true', ' t ',' yes ',' y ',' 1 '] ... más: ... return default
ThePracticalOne
55
Punto menor: probablemente debería preferir ValueError sobre una Excepción simple.
dshepherd
10

siempre puedes hacer algo como

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

el bit en parens evaluaría a False. Esta es solo otra forma de hacerlo sin tener que hacer una llamada a la función real.

holaandre
fuente
1
¿Qué está val = "false"haciendo la línea en este ejemplo? ¿Por qué está ahí? Qué significa eso?
S.Lott 03 de
99
Creo que significa 42.
Geo
@Geo: estoy de acuerdo; pero, ¿cuál fue la pregunta que responde esa afirmación?
S.Lott 03 de
esto es exactamente lo que estaba buscando, evaluar un campo de entrada de un archivo y basarme en el resultado almacenando un valor booleano. gracias.
Jim
9

Un truco simple y genial (basado en lo que publicó @Alan Marchiori), pero usando yaml:

import yaml

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

Si esto es demasiado ancho, se puede refinar probando el resultado del tipo. Si el tipo devuelto por yaml es un str, entonces no se puede convertir a ningún otro tipo (que se me ocurra de todos modos), por lo que podría manejarlo por separado, o simplemente dejar que sea cierto.

No haré ninguna conjetura sobre la velocidad, pero como estoy trabajando con datos yaml bajo Qt gui de todos modos, esto tiene una buena simetría.

Rafe
fuente
1
El yamlmódulo es una biblioteca de terceros: PyYAML
Peter Wood
8

No estoy de acuerdo con ninguna solución aquí, ya que son demasiado permisivos. Esto normalmente no es lo que desea cuando analiza una cadena.

Entonces, aquí la solución que estoy usando:

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)

Y los resultados:

>>> [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

Solo para ser claro porque parece que mi respuesta ofendió a alguien de alguna manera:

El punto es que no desea probar solo un valor y asumir el otro. No creo que siempre quieras asignar absolutamente todo al valor no analizado. Eso produce un código propenso a errores.

Entonces, si sabes en qué quieres codificarlo.

estani
fuente
2
Creo que te estás perdiendo el punto: el objetivo de las respuestas era demostrar el principio general, no decirle a la persona que hizo la pregunta exactamente cómo debería hacerlo. La persona que hizo la pregunta originalmente estaba pensando demasiado en lo que realmente es un problema simple.
Keith Gaughan el
8
@Keith no estoy de acuerdo. El punto es responder la pregunta tal como se hace.
estani
1
La pregunta que se hizo fue cómo convertir una cadena a un booleano. Esa fue la pregunta que respondí. No tengo idea de qué se considera una cadena booleana válida para el póster original, y tú tampoco. Por eso es más importante demostrar el principio general que dar al cartel la respuesta completa. El póster original no necesitaba todo lo que se les explicaba: todo lo que necesitaban era que se demostrara el principio general. A partir de eso, cualquier persona competente obtendrá su respuesta.
Keith Gaughan el
2
@dshepherd isinstance está ahí para estar seguro de que estoy analizando lo que espero. Estoy analizando cadenas de modo que un método car_race.lower () que por casualidad devuelve '1' no debería devolver verdadero, debería arrojar un ValueError. Pero podría ser suficiente en otros casos.
estani
2
@CivFan punto interesante. Aunque lo intenté, y no me pareció tan agradable (para mí). elifes redundante debido a la palabra de retorno, pero le brinda más información sin tener que buscar return. Pero solo soy yo, si hay una violación del estilo PEP, la cambiaría. Sin ninguna otra restricción, siempre debemos buscar legibilidad (y los estándares lo hacen). Gracias por el aviso y comentario interesante!
estani
7

Un dict (realmente, un defaultdict) te da una manera bastante fácil de hacer este truco:

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

Es realmente fácil adaptar este método al comportamiento de conversión exacto que desee: puede completarlo con los valores de Verdad y Falsificación permitidos y dejar que genere una excepción (o que devuelva Ninguno) cuando no se encuentra un valor, o el valor predeterminado es Verdadero, o predeterminado a False, o lo que quieras.

Nate
fuente
5

Probablemente ya tenga una solución, pero para otros que buscan un método para convertir un valor en un valor booleano utilizando valores falsos "estándar" que incluyen Ninguno, [], {} y "" además de falso, no y 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
Chris McMillan
fuente
1
es mejor usar conjuntos, not iny su selección de elementos falsos es algo idiosincrásico.
SilentGhost
5

Simplemente puede usar la función incorporada 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)

y la salida:

a isn't True, a type is <type 'str'>
b is True, b type is <type 'bool'>
lumartor
fuente
1
Esto solo funciona cuando los valores probados son python válidos. "verdadero" y "falso" generarán una excepción.
Gordon Bean
13
Además, es un mal hábito usar 'eval' para analizar porque eval ejecutará un código arbitrario en la cadena. En algunas situaciones, esto puede presentar un gran conjunto de seguridad.
Christopher Barber
77
Esta es una muy mala respuesta. Evaluar una expresión arbitraria para analizar un booleano NO es un buen enfoque.
augurar
5

Otra opción

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

Pero en producción si no necesita ansible y todas sus dependencias, una buena idea es mirar su código fuente y copiar parte de la lógica que necesita.

Maciej Kucia
fuente
4

La regla habitual para la fundición a un bool es que unos literales especiales ( False, 0, 0.0, (), [], {}) son falsas y luego todo lo demás es cierto, por lo que recomiendo lo siguiente:

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

Esta es la versión que escribí. Combina varias de las otras soluciones en una.

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)

Si obtiene una cadena, espera valores específicos, de lo contrario genera una excepción. Si no obtiene una cadena, simplemente deja que el constructor bool lo descubra. Probado estos casos:

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),
    ]
Tom Ekberg
fuente
Usar en strlugar detype('')
pppery
3

Si sabe que su entrada será "Verdadero" o "Falso", entonces, ¿por qué no usar:

def bool_convert(s):
    return s == "True"
Daniel van Flymen
fuente
En realidad no necesitas el if s else Falsebit. Piensa en cómo "False" == "True"ya volverá False.
Taylor Edmiston
Si no está seguro de si la entrada s es una cadena o ya es un booleano, puede agregar if type(s) is bool: return s.
kontur
3

yo suelo

# 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]]
"""
MrHIDEn
fuente
2

Me gusta usar el operador ternario para esto, ya que es un poco más sucinto para algo que parece que no debería ser más de 1 línea.

True if myString=="True" else False
Clayton Rabenda
fuente
1
¿Cómo es más sucinto que my_string == 'True'?
S. de Melo
2

Me doy cuenta de que esta es una publicación antigua, pero algunas de las soluciones requieren bastante código, esto es lo que terminé usando:

def str2bool(value):
    return {"True": True, "true": True}.get(value, False)
Ron E
fuente
77
Eso es funcionalmente equivalente y más complejo que: valor de retorno en ('Verdadero', 'verdadero')
Keith Gaughan
1

Utilice el paquete str2bool pip install str2bool

Director de escuela
fuente
1

Si te gusto solo necesitas boolean de variable que es string. Puede usar destilaciones como se mencionó anteriormente por @jzwiener. Sin embargo, no pude importar y usar el módulo como él sugirió.

En cambio, termino usándolo de esta manera en python3.7

distutils string para bool en python

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

distutils es parte de python std lib, por lo que no es necesario instalarlo. ¡Lo cual es genial! 👍

Gunay Anach
fuente
1

Me gustaría compartir mi solución simple: use el eval(). Convertirá la cadena Truey Falseal tipo booleano adecuado SI la cadena está exactamente en formato de título TrueoFalse siempre en primera letra mayúscula o la función generará un error.

p.ej

>>> eval('False')
False

>>> eval('True')
True

Por supuesto, para la variable dinámica, puede usar simplemente .title()para formatear la cadena booleana.

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

Esto arrojará un error.

>>> 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
Roel
fuente
0

Aquí hay una forma peluda, construida para obtener muchas de las mismas respuestas. Tenga en cuenta que, aunque Python considera ""que es falso y todas las demás cadenas son verdaderas, TCL tiene una idea muy diferente sobre las cosas.

>>> 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 /']"
>>> 

Lo bueno de esto es que es bastante indulgente con los valores que puede usar. Es perezoso sobre convertir cadenas en valores, y es higiénico sobre lo que acepta y rechaza (tenga en cuenta que si la declaración anterior se diera en un indicador tcl, borraría el disco duro de los usuarios).

Lo malo es que requiere que Tkinter esté disponible, lo que generalmente es, pero no universalmente cierto, y más significativamente, requiere que se cree una instancia de Tk, que es relativamente pesada.

Lo que se considera verdadero o falso depende del comportamiento de la Tcl_GetBoolean, que considera 0, false, noy offque es falso y 1, true, yesy ones cierto, mayúsculas y minúsculas. Cualquier otra cadena, incluida la cadena vacía, causa una excepción.

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

idea: verifique si desea que la cadena se evalúe como False; de lo contrario, bool () devuelve True para cualquier cadena no vacía.

xvga
fuente
0

Aquí hay algo que reuní para evaluar la veracidad de una cadena:

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)

más o menos los mismos resultados que usar evalpero más seguro.

tylerl
fuente
0

Solo tenía que hacer esto ... así que tal vez tarde para la fiesta, pero alguien puede encontrarlo útil

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
Rcynic
fuente
0

Si tiene control sobre la entidad que devuelve true/ false, una opción es hacer que devuelva 1/ en 0lugar de true/ false, entonces:

boolean_response = bool(int(response))

La conversión adicional a intmaneja las respuestas de una red, que siempre son cadenas.

Sam Malayek
fuente
-5

Mediante el uso de la función incorporada de Python eval()y el.capitalize() método, puede convertir cualquier cadena "verdadera" / "falsa" (independientemente de las mayúsculas iniciales) en un verdadero booleano de Python.

Por ejemplo:

true_false = "trUE"
type(true_false)

# OUTPUT: <type 'str'>

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

# OUTPUT: <type 'bool'>
elPastor
fuente
44
¿Qué sucede si la cadena contiene #\nshutil.rmtree('/someImportantDirectory')? (¡No lo intentes!)
mastov
@mastov - voto negativo ridículo. Obviamente, si no tiene control de la cadena entrante, debe tomar precauciones, como lo haría con cualquier código. Pero si controla el flujo de trabajo, esta es una solución simple que funciona. No confunda una solución que no sea perfecta en todos los sentidos con una mala respuesta.
elPastor
1
Además de no mencionar los peligros (lo que ya hace que esta sea una mala respuesta): ¿Está proponiendo desinfectar la entrada de antemano? Eso matará la simplicidad de este método, que era su principal ventaja.
mastov
44
Usar evalalgo así de simple es solo pedir una vulnerabilidad.
mastov
1
No todo el código. Pero especialmente el código que convierte cadenas a otros tipos generalmente está fuera de su control. A menudo puede que ni siquiera te des cuenta. Puede decir: "Es mi base de datos (o archivo de configuración), es parte de mi sistema, bajo mi control". Luego le da acceso a algún otro módulo a una base de datos porque: "¿Cuál es el daño? Son solo algunas tablas con cadenas". Pero con evalesas cadenas podría ayudar a alguien a hacerse cargo de todo el sistema.
mastov