tags:

views:

142

answers:

6

Hi, I've got an Nonetype value x, it's generally a number, but could be None. I want to divide it by a number, but python says

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

How could I solve that

+6  A: 

That TypeError only appears when you try to pass int() None (which is the only NoneType value, as far as I know). I would say that your real goal should not be to convert NoneType to int, but to figure out where/why you're getting None instead of a number as expected, and either fix it or handle the None properly.

waffle paradox
A: 

You should check to make sure the value is not None before trying to perform any calculations on it:

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

Note: my_value was intentionally set to None to prove the code works and that the check is being performed.

Soviut
you should use the identity comparison (`is [not] None`)
shylent
-4 You should be encouraging the OP to find out what his real problem is instead of avoiding it. What @shylent said. You set `my_value` unconditionally to None; why? You don't question why the OP thinks he needs to do `int(my_value)` when `my_value` is (if not None) "generally a number".
John Machin
I set my_value to None as a proof of concept, to show my code doesn't fail. I didn't question the OP because there are many reasons why a value may not always be a number and checking that it is before performing calculations is a good idea. There's nothing wrong with simply answering the OP's question, I don't have to do all their homework for them.
Soviut
+2  A: 
int(value or 0)

This will use 0 in the case when you provide any value that Python considers False, such as None, 0, [], "", etc. Since 0 is False, you should only use 0 as the alternative value (otherwise you will find your 0s turning into that value).

int(0 if value is None else value)

This replaces only None with 0. Since we are testing for None specifically, you can use some other value.

kindall
+1  A: 

This can happen if you forget to return a value from a function: it then returns None. Look at all places where you are assigning to that variable, and see if one of them is a function call where the function lacks a return statement.

Jouni K. Seppänen
... or the function has one or more return statements that are just plain `return` instead of `return some_expression`.
John Machin
... or the function contains one or more `return None` statements
John Machin
+5  A: 

In one of the comments, you say:

Somehow I got an Nonetype value, it supposed to be an int, but it's now a Nonetype object

Well, if it's your code, figure out how you're getting None when you expect a number and stop that from happening.

If it's someone else's code, find out the conditions under which it gives None and determine a sensible value to use for that.

detly
+1 for the "right" solution. If your window often breaks mysteriously, figure out why (and catch the vandal who's responsible) instead of blocking the window up ;)
delnan
A: 

A common "Pythonic" way to handle this kind of situation is known as EAFP for "It's easier to ask forgiveness than permission". Which usually means writing code that assumes everything is fine, but then wrapping it with a try..except block just in case to handle things when it's not.

Here's that coding style applied to your problem:

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

answer = my_value / divisor

Or perhaps the even simpler and slightly faster:

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

The inverse and more traditional approach is known as LBYL which stands for "Look before you leap" is what @Soviut and some of the others have suggested. For additional coverage of this topic see my answer and associated comments to the question "Determine whether a key is present in a Python dict" elsewhere on this site.

One potential problem with EAFP is that it can hide the fact that something is wrong with some other part of your code or third-party module you're using, especially when the exceptions frequently occur (and therefore aren't really "exceptional" cases at all).

martineau