tags:

views:

2932

answers:

9

Basically I wanna do:

obj = 'str'
type ( obj ) == string

I tried:

type ( obj ) == type ( string )

and didn't work.

EDIT: Thanks. Also what about the other types? Like there was NoneType that I couldn't replicate.

A: 

You're very close! string is a module, not a type. You probably want to compare the type of obj against the type object for strings, namely str:

type(obj) == str  # this works because str is already a type

Alternatively:

type(obj) == type('')

Note, in Python 2, if obj is a unicode type, then neither of the above will work. Nor will isinstance(). See John's comments to this post for how to get around this... I've been trying to remember it for about 10 minutes now, but was having a memory block!

Jarret Hardie
Use basestring with isinstance() to get both str and unicode.
John Fouhy
John, thank you! I've been trying desperately to remember how I get around the unicode != str problem for 10 minutes now!
Jarret Hardie
-1 for not mentioning that typecheck is a bad idea
nosklo
+10  A: 

isinstance()

in your case, isinstance("this is a string", str) will return true.

you may also want to read this: http://www.canonical.org/~kragen/isinstance/

anthony
I'd say you (the OP) should *definitely* read the referenced link, which gives plenty of details of why checking the type of an object is usually a bad idea, and what you probably should be doing instead.
Jeff Shannon
+1 for the link to the article
nosklo
from memory isinstance( obj, basestring ) will pickup unicode strings too...
Daniel Paull
you should use basestr, not str. otherwise you will not pick unicode. (although for 3.x I think str *is* the basestr)
hasen j
A: 

i think this should do it

if isinstance(obj, str)
Aziz
String isn't a builtin python type.
sysrqb
ya, just realized that (too late :P). Thanks to jjnguy for editing.
Aziz
-1 for not mentioning that typecheck is a bad idea
nosklo
I'm not really that good in Python :P
Aziz
+5  A: 

For other types, check out the types module:

>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True

P.S. Typechecking is a bad idea.

Paolo Bergantino
+7  A: 

isinstance works:

if isinstance(obj, MyClass): do_foo(obj)

but, keep in mind: if it looks like a duck, and if it sounds like a duck, it is a duck.

EDIT: For the None type, you can simply do:

if obj is None: obj = MyClass()
fengshaun
+1 for mentioning duck typing, esp. given your penguin avatar
Jarret Hardie
+1  A: 

You can always use the type(x) == type(y) trick, where y is something with known type.

# check if x is a regular string
type(x) == type('')
# check if x is an integer
type(x) == type(1)
# check if x is a NoneType
type(x) == type(None)

Often there are better ways of doing that, particularly with any recent python. But if you only want to remember one thing, you can remember that.

In this case, the better ways would be:

# check if x is a regular string
type(x) == str
# check if x is either a regular string or a unicode string
type(x) in [str, unicode]
# alternatively:
isinstance(x, basestring)
# check if x is an integer
type(x) == int
# check if x is a NoneType
x is None

Note the last case: there is only one instance of NoneType in python, and that is None. You'll see NoneType a lot in exceptions (TypeError: 'NoneType' object is unsubscriptable -- happens to me all the time..) but you'll hardly ever need to refer to it in code.

Finally, as fengshaun points out, type checking in python is not always a good idea. It's more pythonic to just use the value as though it is the type you expect, and catch (or allow to propagate) exceptions that result from it.

John Fouhy
John, I'm glad you posted your own answer here. This is fabulous. It gives me the opportunity to upvote your expertise here. Cheers.
Jarret Hardie
For what it's worth, isinstance() is the preferred way of checking types in Python (when you have to do it).
David Zaslavsky
A: 

I use type(x) == type(y)

For instance, if I want to check something is an array:

type( x ) == type( [] )

string check:

type( x ) == type( '' ) or type( x ) == type( u'' )

If you want to check against None, use is

x is None
hasen j
-1 for not mentioning that typecheck is a bad idea
nosklo
huh? why is it a bad idea in general? It's only a bad idea for strings (for pre 3.0) because there are two types of strings, str and unicode. For arrays, it's a good idea imho.
hasen j
@hasen: it is a bad idea overall. What if I define my own type that behaves like an array but, say, fetches values from a database? Your code will fail with my type for no reason.
nosklo
@hasen: read the link http://www.canonical.org/~kragen/isinstance/ of the most voted (+7) answer, by voltronw
nosklo
Well, the entire reason (for me atleast) in checking the type is exactly because I want to deal with arrays differently than other types (including types that imitate arrays).
hasen j
@hasen: well, that's a really bad idea and your design is broken. Code shouldn't behave in different ways depending on the type of the object passed. That is bug-prone and prevents code reuse, so is generally frowned upon.
nosklo
You're wrong. I'll give you a concrete example: django has a template rendering shortcut that can accept either a string or an array of strings. Now, both strings and arrays (lists) are iterable, but in this case, the functions needs to differentiate between them.
hasen j
+4  A: 

First, avoid all type comparisons. They're very, very rarely necessary. Sometimes, they help to check parameter types in a function -- even that's rare. Wrong type data will raise an exception, and that's all you'll ever need.

All of the basic conversion functions will map as equal to the type function.

type(9) is int
type(2.5) is float
type('x') is str
type(u'x') is unicode
type(2+3j) is complex

There are a few other cases.

isinstance( 'x', basestring )
isinstance( u'u', basestring )
isinstance( 9, int )
isinstance( 2.5, float )
isinstance( (2+3j), complex )

None, BTW, never needs any of this kind of type checking. None is the only instance of NoneType. The None object is a Singleton. Just check for None

variable is None

BTW, do not use the above in general. Use ordinary exceptions and Python's own natural polymorphism.

S.Lott
A: 

It is because you have to write

s="hello"
type(s) == type("")

type accepts an instance and returns its type. In this case you have to compare two instances' types.

If you need to do preemptive checking, it is better if you check for a supported interface than the type.

The type does not really tell you much, apart of the fact that your code want an instance of a specific type, regardless of the fact that you could have another instance of a completely different type which would be perfectly fine because it implements the same interface.

For example, suppose you have this code

def firstElement(parameter):
    return parameter[0]

Now, suppose you say: I want this code to accept only a tuple.

import types

def firstElement(parameter):
    if type(parameter) != types.TupleType:
         raise TypeError("function accepts only a tuple")
    return parameter[0]

This is reducing the reusability of this routine. It won't work if you pass a list, or a string, or a numpy.array. Something better would be

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    return parameter[0]

but there's no point in doing it: parameter[0] will raise an exception if the protocol is not satisfied anyway... this of course unless you want to prevent side effects or having to recover from calls that you could invoke before failing. (Stupid) example, just to make the point:

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    os.system("rm file")
    return parameter[0]

in this case, your code will raise an exception before running the system() call. Without interface checks, you would have removed the file, and then raised the exception.

Stefano Borini