TAGS :Viewed: 17 - Published at: a few seconds ago

[ Python's type() function and its 'if' related problems ]

So I have the following code:

user_input = raw_input("Enter an integer, string or float:")
input_type = type(user_input)

if input_type == "str":
    print "Your string was %s." % user_input

elif input_type == "int":
    input_type = int(input_type)
    print "Your integer was %d." % user_input

elif input_type == "float":
    input_type = int(input_value)
    print "Your float was %d." % user_input

else:
    print "You did not enter an acceptable input."

This does not work — I believe because of the if — so I changed it to be:

if "str" in input_type

and "int" for the float and integer, but get an error:

Traceback (most recent call last):
File "types.py", line 4, in <module>
if "str" in input_type:
TypeError: argument of type 'type' is not iterable

Why do I get this and how can I fix it?

Answer 1


There are a number of problems here.


user_input = raw_input("Enter an integer, string or float:")
input_type = type(user_input)

Since raw_input always returns a string, input_type will always be str here.


if input_type == "str":
    print "Your string was %s." % user_input

input_type will be str—that is, the actual object representing the string type—not "str", which is just a string. So, this will never be true, and neither will any of your other tests.


Changing this to:

if "str" in input_type:

… can't possibly help anything, unless you're expecting input_type to be either a collection of strings, or a longer string with "str" in the middle of it somewhere. And I can't imagine why you'd expect either.


These lines:

input_type = int(input_type)

… are trying to convert the input_type—which, remember, is a type, like str or int, not the value—to an integer. That can't be what you want.


These lines:

print "Your integer was %d." % user_input

Are printing the original string you received from the user, not the thing you converted to an int. This would work if you used %s rather than %d, but it's probably not what you were trying to do.


print "Your float was %d." % user_input

Even if you fix the previous problem, you can't use %d to print floats.


Next, it's almost always a bad idea to test things by comparing types.

If you really need to do it, it's almost always better to use isinstance(user_input, str) not type(user_input) == str.

But you don't need to do it.


In fact, it's generally better to "ask forgiveness than permission". The right way to find out if something can be converted to an integer is to just try to convert it to an integer, and handle the exception if it can't:

try:
    int_value = int(user_input)
    print "Your integer was %d." % int_value
except ValueError:
    # it's not an int

Answer 2


First of all, "does not work" is not useful. Please in the future explain exactly how it's not working, what you expect and what you get that is unsatisfactory.

Now to your problem: raw_input will always return a string. It is up to you to see if contents of that string conform to something that looks like an integer or a float, and convert accordingly. You know how to convert; the conformity testing would normally be done through a regular expression.

Answer 3


You would need to use isinstance and input to get your code to do what you expect as follows:

user_input = input("Enter an integer, string or float:")

if isinstance(user_input, str):
    print "Your string was %s." % user_input
elif isinstance(user_input, int):
    print "Your integer was %d." % user_input
elif isinstance(user_input, float):
    print "Your float was %f." % user_input
else:
    print "You did not enter an acceptable input."

raw_input always returns a string.

When using input, you must include ' or " around a string input. Also, never use input like this because it can be very dangerous. Use the try except method suggested by abarnert.

Answer 4


While I don't think this is a true duplicate, Differences between isinstance() and type() in python contains a very relevant answer and is good to read.

You would ultimately want to write a try/except that treats the data appropriately.

if isinstance(user_input, str): #or basestring, if you prefer, but Python 3 apparently doesn't use it
    useThisLikeAString(user_input)
try:
    intInput = int(user_input)
    useThisLikeAnInt(user_input)
except TypeError:
    useThisLikeSomethingElse(user_input)

The accepted answer is totally right, in other words, but the link to that discussion is worthwhile.