2010-10-14 79 views
59

Tengo Nonetype valor x, generalmente es un número, pero podría ser None. Quiero dividirlo por un número, pero Python plantea:Cómo convertir Nonetype a int o string?

TypeError: int() argument must be a string or a number, not 'NoneType' 

¿Cómo puedo solucionar esto?

+5

Suponga que None es equivalente a 2771. Pero quizás eso no es lo que quiere. Por favor da más información. – JoshD

+0

De alguna manera obtuve un valor Nonetype, se supone que es un int, pero ahora es un objeto Nonetype, y necesito dividir otro número, luego apareció el error. – user469652

+0

'int (None)' arroja una excepción porque None no se puede convertir a un int. La respuesta a su pregunta es que no se puede hacer. Puede sustituir algo como 0 o 2771, o un elefante rosa, pero sea lo que sea lo que sustituya, no podrá convertir None en un int. – snapshoe

Respuesta

32

En uno de los comentarios, que dicen:

alguna manera me dieron un valor NoneType, se supone que es un int, pero ahora es un objeto NoneType

Si se trata de su código, averigüe cómo va a obtener None cuando espera un número y deje de que ocurra el.

Si se trata de código de otra persona, averiguar las condiciones en que se da None y determinar un valor razonable utilizar para que, 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 ninguna razón para utilizar automáticamente 0 aquí - soluciones que dependen de la -ness "falsa" de None asumen que se desea esto. El DEFAULT_VALUE (si existe) depende completamente del propósito de su código.

+4

+1 para la solución" derecha ". Si su ventana a menudo se rompe misteriosamente, descubra por qué (y atrape al vándalo quién es el responsable) en lugar de bloquear la ventana;) – delnan

+3

Esto no es útil en caso de que esté recuperando claves de un diccionario redis, ya que las claves faltantes serán Ninguna. Si desea sumarlos independientemente de su presencia (que es un comportamiento totalmente aceptable), es posible que deba convertir None en 0 (consulte la respuesta de kindall) – spider

+1

@spider: eso todavía significa que es altamente dependiente de la situación, y "determinar una respuesta sensata". valor "todavía se aplica. – detly

10

Eso TypeError solo aparece cuando intenta pasar int()None (que es el único valor NoneType, que yo sepa). Yo diría que su objetivo real no debe ser convertir NoneType a int o str, sino averiguar dónde/por qué está obteniendo None en lugar de un número como se esperaba, y corregirlo o manejar el None correctamente.

+0

Pasando 'int () 'un número complejo, como' int (1 + 2j) ', también provocará un' TypeError', aunque es probable que eso sea muy poco probable. De todos modos, creo que dices que sería, sin lugar a dudas, en general un buen consejo a seguir. – martineau

1

Usted debe comprobar para asegurarse de que el valor es no 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 fue intencional en Ninguno para probar el código funciona y que el cheque se está realizando.

+1

debe usar la comparación de identidad ('is [not] None') – shylent

+0

-4 Debería alentar al OP a descubrir cuál es su verdadero problema en lugar de evitarlo. Qué dijo @shylent. Estableces 'my_value' incondicionalmente a None; ¿por qué?No cuestiona por qué el OP piensa que necesita hacer 'int (my_value)' cuando 'my_value' es (si no es None)" generalmente un número ". –

+1

Establezco my_value en None como una prueba de concepto, para mostrar que mi código no falla. No cuestioné el OP porque hay muchas razones por las que un valor puede no ser siempre un número y es una buena idea comprobar que es antes de realizar los cálculos. No hay nada de malo simplemente respondiendo la pregunta del OP, no tengo que hacer todas las tareas para ellos. – Soviut

213
int(value or 0) 

Esto utilizará 0 en el caso cuando se proporciona ningún valor que Python considera False, tales como Ninguno, 0, [], "", etc. Dado que 0 es False, sólo se debe utilizar 0 como el valor alternativo (de lo contrario, encontrará que sus 0 se convierten en ese valor).

int(0 if value is None else value) 

Esto reemplaza sólo None con 0. Puesto que estamos probando para None específicamente, se puede utilizar algún otro valor que el de reposición.

+47

user469652 debería considerar hacer de esto la respuesta aceptada. en realidad es útil en comparación con condescendiente – galarant

+0

no estoy seguro si esto resuelve el problema que enfrenta el usuario, es decir. use el nonetype para realizar un cálculo ... actualmente estoy extrayendo datos a través de una API de reposo que devuelve un nonetype que contiene un valor numérico. Si lo configuro en 0 o lo dejo tal como está, no puedo hacer nada con él – br3w5

+1

, así que tengo que encontrar el error en mi código – br3w5

1

Esto puede suceder si olvida devolver un valor de una función: a continuación, devuelve None. Mire todos los lugares donde está asignando esa variable, y vea si una de ellas es una llamada a función en la que la función carece de una declaración de retorno.

+1

... o la función tiene una o más declaraciones de retorno que son simplemente 'return' en lugar de' return some_expression'. –

+0

... o la función contiene una o más declaraciones 'return None' –

10

Una forma común "Pythonic" para manejar este tipo de situación que se conoce como EAFP para "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 bloque try..except por si acaso para manejar las cosas cuando no lo está.

Así es que el 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 tal vez el aún más simple y ligeramente más rápido:

try: 
    answer = my_value/divisor 
except TypeError: 
    answer = 0 

El enfoque inversa y más tradicional es conocida como LBYL que destaca para "Mire antes de saltar" es lo que @Soviut y algunos de los otros han sugerido. Para obtener una cobertura adicional de este tema, consulte mi answer y los comentarios asociados a la pregunta Determine whether a key is present in a dictionary en otro lugar de este sitio.

Un problema potencial con EAFP es que puede ocultar el hecho de que algo está mal en alguna otra parte de su código o módulo de terceros que esté utilizando, especialmente cuando se producen con frecuencia las excepciones (y por lo tanto aren' t casos realmente "excepcionales" en absoluto).

1

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ó el asunto, Yahoo no crea una línea de asunto en el correo electrónico y usted 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 conciso desde un punto de vista de programación; no necesariamente de un 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() 
2

he utilizado con éxito int (x ó 0) para este tipo de error, siempre que ninguno debe ser igual a 0 en la lógica. Tenga en cuenta que esto también se resolverá a 0 en otros casos donde la prueba x devuelve False. p.ej. lista vacía, conjunto, diccionario o cadena de longitud cero. Lo siento, Kindall ya dio esta respuesta.