Tengo un Nonetype
valor x
, generalmente es un número, pero podría serlo None
. Quiero dividirlo por un número, pero Python aumenta:
TypeError: int() argument must be a string or a number, not 'NoneType'
¿Como puedo resolver esto?
En uno de los comentarios, dices:
De alguna manera obtuve un valor Nonetype, se supone que es un int, pero ahora es un objeto Nonetype
Si es su código, averigüe cómo está obteniendo None
cuando espera un número y evite que eso suceda.
Si es el código de otra persona, averigüe las condiciones bajo las cuales se da None
y determine un valor razonable para usarlo, con el código condicional habitual:
result = could_return_none(x)
if result is None:
result = DEFAULT_VALUE
...o incluso...
if x == THING_THAT_RESULTS_IN_NONE:
result = DEFAULT_VALUE
else:
result = could_return_none(x) # But it won't return None, because we've restricted the domain.
No hay razón para usar automáticamente 0
aquí - soluciones que dependen de la "falsedad" - de None
asumir que querrás esto. El DEFAULT_VALUE
(si es que existe) depende completamente del propósito de su código.
int(value or 0)
Esto usará 0 en el caso de que proporciones cualquier valor que Python considere False
, como Ninguno, 0, [], "", etc. Dado que 0 es False
, solo debes usar 0 como valor alternativo (de lo contrario, encontrarás tus 0s convirtiéndose en ese valor).
int(0 if value is None else value)
Esto se reemplaza solo None
con 0. Dado que estamos probando None
específicamente, puede usar algún otro valor como reemplazo.
(value or 0)
, sin la conversión de tipo int, si aseguramos que el valor solo puede ser None o int
Una forma "Pythonic" común de manejar este tipo de situación se conoce como EAFP por " Es más fácil pedir perdón que permiso ". Lo que generalmente significa escribir código que asume que todo está bien, pero luego envolverlo con un try..except
bloque por si acaso para manejar las cosas cuando no lo está.
Aquí está ese estilo de codificación aplicado a su problema:
try:
my_value = int(my_value)
except TypeError:
my_value = 0 # or whatever you want to do
answer = my_value / divisor
O quizás el más simple y un poco más rápido:
try:
answer = int(my_value) / divisor
except TypeError:
answer = 0
El enfoque inverso y más tradicional se conoce como LBYL, que significa " Mira antes de saltar ", es lo que han sugerido @Soviut y algunos de los otros. Para obtener información adicional sobre este tema, consulte mi respuesta y los comentarios asociados a la pregunta Determinar si una clave está presente en un diccionario en otra parte de este sitio.
Un problema potencial con EAFP es que puede ocultar el hecho de que algo está mal con alguna otra parte de su código o módulo de terceros que está utilizando, especialmente cuando las excepciones ocurren con frecuencia (y por lo tanto no son casos realmente "excepcionales" en absoluto).
Eso TypeError
solo aparece cuando intentas pasar int()
None
(que es el único NoneType
valor, hasta donde yo sé). Yo diría que su objetivo real no debería ser convertir NoneType
a int
o str
, sino averiguar dónde / por qué está obteniendo en None
lugar de un número como se esperaba, y solucionarlo o manejarlo None
correctamente.
int()
un número complejo, como int(1+2j)
, también hará TypeError
que se aumente, aunque hay que admitir que es muy poco probable. Independientemente, creo que dices que sería, sin lugar a dudas, un buen consejo a seguir.
En Python 3 también puede usar la palabra clave "o". De esta manera:
foo = bar or 0
foo2 = bar or ""
He utilizado con éxito int (xo 0) para este tipo de error, siempre que Ninguno sea igual a 0 en la lógica. Tenga en cuenta que esto también se resolverá en 0 en otros casos en los que probar x devuelve False. por ejemplo, lista vacía, conjunto, diccionario o cadena de longitud cero. Lo siento, Kindall ya dio esta respuesta.
Esto puede suceder si olvida devolver un valor de una función: luego devuelve Ninguno. Mire todos los lugares donde está asignando a esa variable y vea si uno de ellos es una llamada de función donde la función carece de una declaración de retorno.
return
lugar de return some_expression
.
return None
declaraciones
Debe verificar para asegurarse de que el valor no sea Ninguno antes de intentar realizar cualquier cálculo en él:
my_value = None
if my_value is not None:
print int(my_value) / 2
Nota: my_value
se estableció intencionalmente en Ninguno para probar que el código funciona y que se está realizando la verificación.
is [not] None
)
my_value
incondicionalmente en Ninguno; ¿por qué? No se cuestiona por qué el OP cree que debe hacerlo int(my_value)
cuando my_value
es (si no Ninguno) "generalmente un número".
Estaba teniendo el mismo problema al usar las funciones de correo electrónico de Python. A continuación se muestra el código que estaba tratando de recuperar el asunto del correo electrónico en una variable. Esto funciona bien para la mayoría de los correos electrónicos y la variable se completa. Si recibe un correo electrónico de Yahoo o similar y el remitente no completó la línea de asunto, Yahoo no crea una línea de asunto en el correo electrónico y obtiene un NoneType devuelto por la función. Martineau proporcionó una respuesta correcta al igual que Soviut. La respuesta de IMO Soviut es más concisa desde el punto de vista de la programación; no necesariamente de uno de Python. Aquí hay un código para mostrar la técnica:
import sys, email, email.Utils
afile = open(sys.argv[1], 'r')
m = email.message_from_file(afile)
subject = m["subject"]
# Soviut's Concise test for unset variable.
if subject is None:
subject = "[NO SUBJECT]"
# Alternative way to test for No Subject created in email (Thanks for NoneThing Yahoo!)
try:
if len(subject) == 0:
subject = "[NO SUBJECT]"
except TypeError:
subject = "[NO SUBJECT]"
print subject
afile.close()
En algunas situaciones, es útil tener una función para convertir None en int cero:
def nz(value):
'''
Convert None to int zero else return value.
'''
if value == None:
return 0
return value
int(None)
lanza una excepción porque None no se puede convertir en un int. La respuesta a tu pregunta es que no se puede hacer. Puede sustituir algo, como 0 o 2771, o un elefante rosa, pero lo que sea que sustituya, no podrá convertir None en un int.None
en un elefante rosa tampoco es bueno, a menos que esté trabajando en algún sistema numérico que defina formalmente la división de un número por un elefante rosa (y haya escrito el código para respaldarlo)