Załóżmy, że Brak jest odpowiednikiem 2771. Ale może nie tego chcesz. Proszę podać więcej informacji.
JoshD,
W jakiś sposób uzyskałem wartość Nonetype, przypuszczalnie jest to int, ale teraz jest to obiekt Nonetype i muszę podzielić inną liczbę, a potem pojawił się błąd.
user469652
int(None)zgłasza wyjątek, ponieważ None nie może zostać przekonwertowana na int. Odpowiedź na Twoje pytanie brzmi: nie da się tego zrobić. Możesz podstawić coś, na przykład 0, 2771 lub różowego słonia, ale cokolwiek zastąpisz, nadal nie będziesz w stanie przekonwertować None na int.
snapshoe
7
@ ma3204. konwersja Nonena różowego słonia też nie jest dobra, chyba że pracujesz nad jakimś systemem liczbowym, który formalnie definiuje dzielenie liczby przez różowego słonia (i napisałeś kod, aby ją wykonać)
aaronasterling
Odpowiedzi:
49
W jednym z komentarzy mówisz:
W jakiś sposób otrzymałem wartość Nonetype, przypuszczalnie to int, ale teraz jest to obiekt Nonetype
Jeśli to twój kod, dowiedz się, jak otrzymujesz, Nonekiedy spodziewasz się liczby, i powstrzymaj to .
Jeśli jest to kod kogoś innego, dowiedz się, w jakich warunkach daje Nonei określ sensowną wartość do użycia, używając zwykłego kodu warunkowego:
result = could_return_none(x)
if result isNone:
result = DEFAULT_VALUE
...lub nawet...
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.
Nie ma powodu, aby używać 0tutaj automatycznie - rozwiązań, które zależą od „fałszywego” Nonezałożenia, że będziesz tego chciał. DEFAULT_VALUE(Jeśli w ogóle istnieje) całkowicie zależy od celu w kodzie.
+1 za „właściwe” rozwiązanie. Jeśli twoje okno często w tajemniczy sposób pęka, dowiedz się, dlaczego (i złap wandala, który jest odpowiedzialny) zamiast blokować okno;)
3
Nie jest to przydatne na przykład w przypadku pobierania kluczy ze słownika redis, ponieważ brakującymi kluczami będą Brak. Jeśli chcesz je zsumować niezależnie od ich obecności (co jest całkowicie akceptowalnym zachowaniem), może być konieczne przekonwertowanie None na 0 (zobacz odpowiedź kindall)
pająk
1
@spider - to nadal oznacza, że jest wysoce zależny od sytuacji, a „określ rozsądną wartość” nadal ma zastosowanie.
detly
Argument pająka jest całkiem słuszny, ta odpowiedź po prostu mówi, że zrobiłeś coś źle, ale Brak nie oznacza, że oznacza to nieznaną wartość, która może wskazywać, że zrobiłeś coś źle, lub ponieważ pająk zasugerował brakującą wartość, generalnie powinna być 0 lub ewentualnie 1, dla większości możliwych zastosowań None, gdzie oczekiwana jest liczba całkowita.
Glen Fletcher
@glenflet Jeśli nie wiesz, jaka jest domena wejściowa i specyfikacja Twojej funkcji, obcy w Internecie nie będzie w stanie Ci tego powiedzieć. Jeśli wiesz, ale nie znasz składni konwersji, to jest to zupełnie inne pytanie niż zadane tutaj.
detly
318
int(value or0)
Spowoduje to użycie 0 w przypadku, gdy podasz jakąkolwiek wartość uznaną przez Pythona False, taką jak Brak, 0, [], "" itd. Ponieważ 0 to False, powinieneś używać tylko 0 jako wartości alternatywnej (w przeciwnym razie znajdziesz swoje 0 zamieniając się w tę wartość).
int(0if value isNoneelse value)
To zastępuje tylko None0. Ponieważ testujemy Nonekonkretnie, możesz użyć innej wartości jako zamiennika.
user469652, zamiast tego powinieneś rozważyć zaakceptowanie tej odpowiedzi. jest rzeczywiście pomocny w przeciwieństwie do protekcjonalnego
galarant
Nie jestem pewien, czy to rozwiązuje problem, z którym boryka się użytkownik, tj. użyj typu nonetype do wykonania obliczeń ... obecnie pobieram dane za pośrednictwem interfejsu API REST, który zwraca wartość typu nonetype zawierającą wartość liczbową. Jeśli
ustawię
2
Jest to zdecydowanie najlepsza odpowiedź, biorąc pod uwagę pytanie, ponieważ użytkownik wskazuje, że należy się spodziewać None, podobnie jak prawdopodobnie funkcji, żądającej wartości czegoś zwracającego None, aby wskazać, że wartość jest nieznana, w tym przypadku None powinno stać się wartością domyślną w jego przypadku użycia, który zwykle wynosi 0. rozważ izip_longest, domyślny argument, jeśli inny ma inny domyślny (parzysty typ), to domyślnym powinno być Brak, który jest następnie zastępowany domyślnym, jednak ciągiem. <align_n> (str, w) przyjmuje tylko liczbę całkowitą jako szerokość.
Glen Fletcher
2
Użyłem tego i było eleganckie i rozwiązało moje problemy.
Dan Safee
1
możemy użyć (value or 0)- bez rzutowania typu int - jeśli zapewnimy, że wartość może być tylko wartością None lub int
hashlash
17
Powszechny „Pythonowy” sposób radzenia sobie z tego rodzaju sytuacjami jest znany jako EAFP, czyli „ łatwiej prosić o przebaczenie niż o pozwolenie ”. Co zwykle oznacza napisanie kodu, który zakłada, że wszystko jest w porządku, ale następnie owinięcie go try...exceptblokiem do obsługi rzeczy - tak na wszelki wypadek - tak nie jest.
Oto styl kodowania zastosowany do Twojego problemu:
try:
my_value = int(my_value)
except TypeError:
my_value = 0# or whatever you want to do
answer = my_value / divisor
Odwrotne i bardziej tradycyjne podejście jest znane jako LBYL, co oznacza „ Look before you leap ”, co zasugerował @Soviut i niektórzy inni. Aby uzyskać dodatkowe omówienie tego tematu, zobacz moją odpowiedź i powiązane komentarze do pytania Ustal, czy klucz znajduje się w słowniku w innym miejscu na tej stronie.
Jednym z potencjalnych problemów z EAFP jest to, że może on ukryć fakt, że coś jest nie tak z inną częścią twojego kodu lub modułem innej firmy, z której korzystasz, zwłaszcza gdy często występują wyjątki (i dlatego nie są to naprawdę „wyjątkowe” przypadki w ogóle).
Że TypeErrorpojawia się tylko wtedy, gdy próbujesz przekazać int()None(który jest tylko NoneTypewartość, o ile wiem). Powiedziałbym, że Twoim prawdziwym celem nie powinno być przekonwertowanie NoneTypena intlub str, ale Noneustalenie , gdzie / dlaczego otrzymujesz zamiast liczby zgodnie z oczekiwaniami, i albo napraw go, albo Noneodpowiednio obsłuż.
Przekazanie int()liczby zespolonej, takiej jak int(1+2j), również spowoduje TypeErrorpodniesienie a, chociaż trzeba przyznać, że jest to prawdopodobnie bardzo mało prawdopodobne. Niezależnie od tego, myślę, że powiedziałbyś, że bez wątpienia byłaby to ogólnie dobra rada do naśladowania.
martineau
5
W Pythonie 3 możesz również użyć słowa kluczowego „lub”. Tą drogą:
Z powodzeniem użyłem int (x lub 0) dla tego typu błędu, o ile None powinien być równy 0 w logice. Zauważ, że rozwiąże to również do 0 w innych przypadkach, gdy testowanie x zwraca False. np. pusta lista, zbiór, słownik lub łańcuch o zerowej długości. Przepraszamy, Kindall już udzielił tej odpowiedzi.
Może się to zdarzyć, jeśli zapomnisz zwrócić wartość z funkcji: zwraca ona wtedy None. Spójrz na wszystkie miejsca, w których przypisujesz tę zmienną, i zobacz, czy jedno z nich jest wywołaniem funkcji, w którym funkcja nie zawiera instrukcji return.
powinieneś użyć porównania tożsamości ( is [not] None)
shylent
-4 Powinieneś zachęcać OP, aby dowiedział się, jaki jest jego prawdziwy problem, zamiast go unikać. Co powiedział @shylent. Ustawić my_valuebezwarunkowo None; czemu? Nie zastanawiasz się, dlaczego OP uważa, że musi to zrobić, int(my_value)kiedy my_value(jeśli nie Brak) „ogólnie jest liczbą”.
John Machin
1
Ustawiłem my_value na None jako dowód koncepcji, aby pokazać, że mój kod nie zawodzi. Nie kwestionowałem OP, ponieważ istnieje wiele powodów, dla których wartość może nie zawsze być liczbą i sprawdzenie, czy jest przed wykonaniem obliczeń, jest dobrym pomysłem. Nie ma nic złego w zwykłej odpowiedzi na pytanie OP, nie muszę odrabiać za nich całej pracy domowej.
Soviut
1
Miałem ten sam problem podczas korzystania z funkcji poczty e-mail w języku Python. Poniżej znajduje się kod, który próbowałem pobrać temat wiadomości e-mail do zmiennej. Działa to dobrze w przypadku większości wiadomości e-mail i zapełniania zmiennej. Jeśli otrzymasz wiadomość e-mail z Yahoo lub podobnego, a nadawca nie wypełnił tematu, Yahoo nie utworzy tematu wiadomości e-mail, a funkcja zwróci wartość NoneType. Martineau udzielił poprawnej odpowiedzi, podobnie jak Soviut. Odpowiedź IMO Soviut jest bardziej zwięzła z punktu widzenia programowania; niekoniecznie z Pythona. Oto kod pokazujący technikę:
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 isNone:
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()
int(None)
zgłasza wyjątek, ponieważ None nie może zostać przekonwertowana na int. Odpowiedź na Twoje pytanie brzmi: nie da się tego zrobić. Możesz podstawić coś, na przykład 0, 2771 lub różowego słonia, ale cokolwiek zastąpisz, nadal nie będziesz w stanie przekonwertować None na int.None
na różowego słonia też nie jest dobra, chyba że pracujesz nad jakimś systemem liczbowym, który formalnie definiuje dzielenie liczby przez różowego słonia (i napisałeś kod, aby ją wykonać)Odpowiedzi:
W jednym z komentarzy mówisz:
Jeśli to twój kod, dowiedz się, jak otrzymujesz,
None
kiedy spodziewasz się liczby, i powstrzymaj to .Jeśli jest to kod kogoś innego, dowiedz się, w jakich warunkach daje
None
i określ sensowną wartość do użycia, używając zwykłego kodu warunkowego:result = could_return_none(x) if result is None: result = DEFAULT_VALUE
...lub nawet...
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.
Nie ma powodu, aby używać
0
tutaj automatycznie - rozwiązań, które zależą od „fałszywego”None
założenia, że będziesz tego chciał.DEFAULT_VALUE
(Jeśli w ogóle istnieje) całkowicie zależy od celu w kodzie.źródło
int(value or 0)
Spowoduje to użycie 0 w przypadku, gdy podasz jakąkolwiek wartość uznaną przez Pythona
False
, taką jak Brak, 0, [], "" itd. Ponieważ 0 toFalse
, powinieneś używać tylko 0 jako wartości alternatywnej (w przeciwnym razie znajdziesz swoje 0 zamieniając się w tę wartość).int(0 if value is None else value)
To zastępuje tylko
None
0. Ponieważ testujemyNone
konkretnie, możesz użyć innej wartości jako zamiennika.źródło
(value or 0)
- bez rzutowania typu int - jeśli zapewnimy, że wartość może być tylko wartością None lub intPowszechny „Pythonowy” sposób radzenia sobie z tego rodzaju sytuacjami jest znany jako EAFP, czyli „ łatwiej prosić o przebaczenie niż o pozwolenie ”. Co zwykle oznacza napisanie kodu, który zakłada, że wszystko jest w porządku, ale następnie owinięcie go
try...except
blokiem do obsługi rzeczy - tak na wszelki wypadek - tak nie jest.Oto styl kodowania zastosowany do Twojego problemu:
try: my_value = int(my_value) except TypeError: my_value = 0 # or whatever you want to do answer = my_value / divisor
A może jeszcze prostszy i nieco szybszy:
try: answer = int(my_value) / divisor except TypeError: answer = 0
Odwrotne i bardziej tradycyjne podejście jest znane jako LBYL, co oznacza „ Look before you leap ”, co zasugerował @Soviut i niektórzy inni. Aby uzyskać dodatkowe omówienie tego tematu, zobacz moją odpowiedź i powiązane komentarze do pytania Ustal, czy klucz znajduje się w słowniku w innym miejscu na tej stronie.
Jednym z potencjalnych problemów z EAFP jest to, że może on ukryć fakt, że coś jest nie tak z inną częścią twojego kodu lub modułem innej firmy, z której korzystasz, zwłaszcza gdy często występują wyjątki (i dlatego nie są to naprawdę „wyjątkowe” przypadki w ogóle).
źródło
Że
TypeError
pojawia się tylko wtedy, gdy próbujesz przekazaćint()
None
(który jest tylkoNoneType
wartość, o ile wiem). Powiedziałbym, że Twoim prawdziwym celem nie powinno być przekonwertowanieNoneType
naint
lubstr
, aleNone
ustalenie , gdzie / dlaczego otrzymujesz zamiast liczby zgodnie z oczekiwaniami, i albo napraw go, alboNone
odpowiednio obsłuż.źródło
int()
liczby zespolonej, takiej jakint(1+2j)
, również spowodujeTypeError
podniesienie a, chociaż trzeba przyznać, że jest to prawdopodobnie bardzo mało prawdopodobne. Niezależnie od tego, myślę, że powiedziałbyś, że bez wątpienia byłaby to ogólnie dobra rada do naśladowania.W Pythonie 3 możesz również użyć słowa kluczowego „lub”. Tą drogą:
foo = bar or 0 foo2 = bar or ""
źródło
Z powodzeniem użyłem int (x lub 0) dla tego typu błędu, o ile None powinien być równy 0 w logice. Zauważ, że rozwiąże to również do 0 w innych przypadkach, gdy testowanie x zwraca False. np. pusta lista, zbiór, słownik lub łańcuch o zerowej długości. Przepraszamy, Kindall już udzielił tej odpowiedzi.
źródło
Może się to zdarzyć, jeśli zapomnisz zwrócić wartość z funkcji: zwraca ona wtedy None. Spójrz na wszystkie miejsca, w których przypisujesz tę zmienną, i zobacz, czy jedno z nich jest wywołaniem funkcji, w którym funkcja nie zawiera instrukcji return.
źródło
return
zamiastreturn some_expression
.return None
instrukcjiPrzed wykonaniem jakichkolwiek obliczeń należy sprawdzić, czy wartość nie jest ustawiona na Brak:
my_value = None if my_value is not None: print int(my_value) / 2
Uwaga:
my_value
celowo ustawiono wartość Brak, aby udowodnić, że kod działa i że sprawdzanie jest wykonywane.źródło
is [not] None
)my_value
bezwarunkowo None; czemu? Nie zastanawiasz się, dlaczego OP uważa, że musi to zrobić,int(my_value)
kiedymy_value
(jeśli nie Brak) „ogólnie jest liczbą”.Miałem ten sam problem podczas korzystania z funkcji poczty e-mail w języku Python. Poniżej znajduje się kod, który próbowałem pobrać temat wiadomości e-mail do zmiennej. Działa to dobrze w przypadku większości wiadomości e-mail i zapełniania zmiennej. Jeśli otrzymasz wiadomość e-mail z Yahoo lub podobnego, a nadawca nie wypełnił tematu, Yahoo nie utworzy tematu wiadomości e-mail, a funkcja zwróci wartość NoneType. Martineau udzielił poprawnej odpowiedzi, podobnie jak Soviut. Odpowiedź IMO Soviut jest bardziej zwięzła z punktu widzenia programowania; niekoniecznie z Pythona. Oto kod pokazujący technikę:
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()
źródło
W niektórych sytuacjach pomocne jest posiadanie funkcji konwertującej None na int zero:
def nz(value): ''' Convert None to int zero else return value. ''' if value == None: return 0 return value
źródło