Come convertire Nonetype in int o string?


96

Ho un Nonetypevalore x, generalmente è un numero, ma potrebbe esserlo None. Voglio dividerlo per un numero, ma Python solleva:

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

Come posso risolvere questo?


5
Supponi che Nessuno sia equivalente a 2771. Ma forse non è quello che vuoi. Si prega di fornire maggiori informazioni.
JoshD,

In qualche modo ho ottenuto un valore Nonetype, dovrebbe essere un int, ma ora è un oggetto Nonetype e devo dividere un altro numero, quindi si è verificato l'errore.
user469652

int(None)genera un'eccezione perché None non può essere convertito in un int. La risposta alla tua domanda è che non si può fare. Puoi sostituire qualcosa, come 0, o 2771, o un elefante rosa, ma qualunque cosa tu sostituisca, non sarai comunque in grado di convertire None in un int.
snapshoe

7
@ ma3204. anche la conversione Nonein un elefante rosa non va bene, a meno che tu non stia lavorando a un sistema numerico che definisce formalmente la divisione di un numero da parte di un elefante rosa (e hai scritto il codice per
eseguirne il

Risposte:


49

In uno dei commenti, dici:

In qualche modo ho ottenuto un valore Nonetype, dovrebbe essere un int, ma ora è un oggetto Nonetype

Se è il tuo codice, scopri come stai ottenendo Nonequando ti aspetti un numero e impedisci che accada.

Se è il codice di qualcun altro, scopri le condizioni in cui fornisce Nonee determina un valore ragionevole da usare per quello, con il solito codice condizionale:

result = could_return_none(x)

if result is None:
    result = DEFAULT_VALUE

...o anche...

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.

Non c'è motivo per usare automaticamente 0qui - soluzioni che dipendono dalla "falsa" -nessunita 'di Nonepresumere che lo vorrai. Il DEFAULT_VALUE(se esiste) dipende completamente dallo scopo del codice.


5
+1 per la soluzione "giusta". Se la tua finestra spesso si rompe misteriosamente, scopri perché (e cattura il vandalo responsabile) invece di bloccare la finestra;)

3
Ciò non è utile nel caso in cui si stiano recuperando chiavi da un dizionario redis, ad esempio, poiché le chiavi mancanti saranno Nessuna. Se vuoi sommarli indipendentemente dalla loro presenza (che è un comportamento totalmente accettabile), potresti dover convertire Nessuno in 0 (vedi risposta gentile)
spider

1
@spider - questo significa ancora che dipende molto dalla situazione e "determina un valore ragionevole" si applica ancora.
detly

Il punto di Spider è abbastanza valido questa risposta fondamentalmente dice solo che hai fatto qualcosa di sbagliato, ma Nessuno non significa che significhi un valore sconosciuto, che potrebbe indicare che hai fatto qualcosa di sbagliato, o poiché spider ha suggerito un valore mancante, in generale dovrebbe essere 0 o possibilmente 1, per la maggior parte dei possibili usi di None dove è previsto un numero intero.
Glen Fletcher

@glenflet Se non sai quale sia il dominio di input e le specifiche della tua funzione, uno sconosciuto su Internet non sarà in grado di dirtelo. Se conosci, ma non conosci la sintassi per convertirlo, è una domanda completamente diversa da quella posta qui.
detly

312
int(value or 0)

Questo userà 0 nel caso in cui fornisci un valore che Python considera False, come Nessuno, 0, [], "", ecc. Poiché 0 èFalse , dovresti usare solo 0 come valore alternativo (altrimenti troverai i tuoi 0 trasformandosi in quel valore).

int(0 if value is None else value)

Sostituisce solo Nonecon 0. Dato che stiamo testando Nonespecificamente, puoi usare qualche altro valore come sostituzione.


64
user469652 dovresti invece considerare di rendere questa la risposta accettata. in realtà è utile al contrario del condiscendente
galante

Non sono sicuro che questo risolva il problema che l'utente sta affrontando, ad es. usa il nonetype per eseguire un calcolo ... Attualmente sto estraendo i dati tramite un'api rest che restituisce un nonetype contenente un valore numerico. Se lo imposto a 0 o lo lascio così com'è non posso farci niente
br3w5

2
Questa è decisamente la risposta migliore, data la domanda, poiché l'utente indica che Nessuno, dovrebbe essere previsto, come forse una funzione, che richiede il valore di qualcosa che restituisce Nessuno per indicare che il valore è sconosciuto, in questo caso Nessuno dovrebbe diventare il valore predefinito nel suo caso d'uso, che di solito sarebbe 0. considera izip_longest, argomento predefinito, se il diverso ha un valore predefinito diverso (tipo pari), quindi il valore predefinito dovrebbe essere Nessuno che viene quindi sostituito con un valore predefinito, comunque stringa. <align_n> (str, w) accetta solo un intero per la larghezza.
Glen Fletcher

2
Ho usato questo ed è stato elegante e ha risolto i miei problemi.
Dan Safee

1
possiamo usare (value or 0)- senza il casting di tipo int - se ci assicuriamo che il valore può essere solo None o int
hashlash

16

Un modo comune "pitonico" per gestire questo tipo di situazione è noto come EAFP per " è più facile chiedere perdono che permesso ". Il che di solito significa scrivere codice che presume che tutto vada bene, ma poi avvolgerlo con un try..exceptblocco nel caso in cui gestire le cose quando non lo è.

Ecco lo stile di codifica applicato al tuo problema:

try:
    my_value = int(my_value)
except TypeError:
    my_value = 0  # or whatever you want to do

answer = my_value / divisor

O forse ancora più semplice e leggermente più veloce:

try:
    answer = int(my_value) / divisor
except TypeError:
    answer = 0

L'approccio inverso e più tradizionale è noto come LBYL che sta per " Look before you leap ", è quello che hanno suggerito @Soviut e alcuni altri. Per una copertura aggiuntiva di questo argomento, vedere la mia risposta e i commenti associati alla domanda Determinare se una chiave è presente in un dizionario altrove su questo sito.

Un potenziale problema con EAFPèche può nascondere il fatto che qualcosa non va con qualche altra parte del tuo codice o modulo di terze parti che stai usando, specialmente quando si verificano frequentemente le eccezioni (e quindi non sono davvero casi "eccezionali" affatto).


11

Questo TypeErrorappare solo quando si tenta di passare int() None(che è l'unico NoneTypevalore, per quanto ne so). Direi che il tuo vero obiettivo non dovrebbe essere quello di convertire NoneTypein into str, ma di capire dove / perché stai ottenendo Noneinvece di un numero come previsto, e risolverlo o gestirlo Nonecorrettamente.


Il passaggio di int()un numero complesso, ad esempio int(1+2j), causerà anche l' TypeErroraumento di a, anche se è probabile che sia molto improbabile. Indipendentemente da ciò, penso che tu dici che sarebbe, senza dubbio, generalmente un buon consiglio da seguire.
martineau

5

In Python 3 puoi usare anche la parola chiave "o". Per di qua:

foo = bar or 0
foo2 = bar or ""

2

Ho usato con successo int (x o 0) per questo tipo di errore, a condizione che Nessuno debba essere uguale a 0 nella logica. Nota che questo si risolverà anche a 0 in altri casi in cui il test x restituisce False. es. elenco vuoto, set, dizionario o stringa di lunghezza zero. Mi dispiace, Kindall ha già dato questa risposta.


1

Questo può accadere se ti dimentichi di restituire un valore da una funzione: poi restituisce Nessuno. Guarda tutti i punti in cui stai assegnando a quella variabile e vedi se uno di loro è una chiamata di funzione in cui alla funzione manca un'istruzione return.


1
... oppure la funzione ha una o più istruzioni return che sono semplicemente semplici returninvece di return some_expression.
John Machin

... oppure la funzione contiene una o più return Noneistruzioni
John Machin

1

Dovresti controllare per assicurarti che il valore non sia Nessuno prima di provare a eseguire qualsiasi calcolo su di esso:

my_value = None
if my_value is not None:
    print int(my_value) / 2

Nota: è my_value stato intenzionalmente impostato su Nessuno per dimostrare che il codice funziona e che il controllo viene eseguito.


1
dovresti usare il confronto di identità ( is [not] None)
shylent

-4 Dovresti incoraggiare l'OP a scoprire qual è il suo vero problema invece di evitarlo. Cosa ha detto @shylent. Hai impostato my_valueincondizionatamente su Nessuno; perché? Non ti chiedi perché l'OP pensa di doverlo fareint(my_value) quando my_valueè (se non Nessuno) "generalmente un numero".
John Machin

1
Ho impostato my_value su Nessuno come prova del concetto, per mostrare che il mio codice non fallisce. Non ho messo in dubbio l'OP perché ci sono molte ragioni per cui un valore potrebbe non essere sempre un numero e controllare che lo sia prima di eseguire i calcoli è una buona idea. Non c'è niente di sbagliato nel rispondere semplicemente alla domanda dell'OP, non devo fare tutti i compiti per loro.
Soviut

1

Avevo lo stesso problema usando le funzioni di posta elettronica di Python. Di seguito è riportato il codice che stavo cercando di recuperare l'oggetto dell'email in una variabile. Funziona bene per la maggior parte delle email e la variabile viene popolata. Se ricevi un'e-mail da Yahoo o simili e il mittente non ha compilato la riga dell'oggetto, Yahoo non crea una riga dell'oggetto nell'email e ottieni un NoneType restituito dalla funzione. Martineau ha fornito una risposta corretta così come Soviut. La risposta di IMO Soviut è più concisa dal punto di vista della programmazione; non necessariamente da uno Python. Ecco del codice per mostrare la tecnica:

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

1

In alcune situazioni è utile avere una funzione per convertire None in int zero:

def nz(value):

    '''
    Convert None to int zero else return value.
    '''

    if value == None:
        return 0
    return value
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.