Categories
dictionary python typeof types

Determine the type of an object?

2047

Is there a simple way to determine if a variable is a list, dictionary, or something else?

14

  • 50

    While in general I agree with you, there are situations where it is helpful to know. In this particular case I was doing some quick hacking that I eventually rolled back, so you are correct this time. But in some cases – when using reflection, for example – it is important to know what type of object you are dealing with.

    Feb 9, 2010 at 13:10


  • 70

    @S.Lott I’d disagree with that; by being able to know the type, you can deal with some pretty variant input and still do the right thing. It lets you work around interface issues inherent with relying on pure duck-typing (eg, the .bark() method on a Tree means something entirely different than on a Dog.) For example, you could make a function that does some work on a file that accepts a string (eg, a path), a path object, or a list. All have different interfaces, but the final result is the same: do some operation on that file.

    – Robert P

    Jul 21, 2011 at 21:33


  • 24

    @S.Lott I hoped it would be obvious that it’s a contrived example; nonetheless it’s a major failing point of duck typing, and one that try doesn’t help with. For example, if you knew that a user could pass in a string or an array, both are index-able, but that index means something completely different. Simply relying on a try-catch in those cases will fail in unexpected and strange ways. One solution is to make a separate method, another to add a little type checking. I personally prefer polymorphic behavior over multiple methods that do almost the same thing…but that’s just me 🙂

    – Robert P

    Jul 22, 2011 at 0:57

  • 23

    @S.Lott, what about unit testing? Sometimes you want your tests to verify that a function is returning something of the right type. A very real example is when you have class factory.

    Sep 24, 2012 at 16:23

  • 18

    For a less contrived example, consider a serializer/deserializer. By definition you are converting between user-supplied objects and a serialized representation. The serializer needs to determine the type of object you passed in, and you may not have adequate information to determine the deserialized type without asking the runtime (or at the very least, you may need it for sanity checking to catch bad data before it enters your system!)

    – Karl

    May 13, 2013 at 2:35


2222

There are two built-in functions that help you identify the type of an object. You can use type() if you need the exact type of an object, and isinstance() to check an object’s type against something. Usually, you want to use isinstance() most of the times since it is very robust and also supports type inheritance.


To get the actual type of an object, you use the built-in type() function. Passing an object as the only parameter will return the type object of that object:

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True

This of course also works for custom types:

>>> class Test1 (object):
        pass
>>> class Test2 (Test1):
        pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True

Note that type() will only return the immediate type of the object, but won’t be able to tell you about type inheritance.

>>> type(b) is Test1
False

To cover that, you should use the isinstance function. This of course also works for built-in types:

>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

isinstance() is usually the preferred way to ensure the type of an object because it will also accept derived types. So unless you actually need the type object (for whatever reason), using isinstance() is preferred over type().

The second parameter of isinstance() also accepts a tuple of types, so it’s possible to check for multiple types at once. isinstance will then return true, if the object is of any of those types:

>>> isinstance([], (tuple, list, set))
True

16

  • 70

    I think it’s clearer to use is instead of == as the types are singletons

    Feb 8, 2010 at 22:01

  • 18

    @gnibbler, In the cases you would be typechecking (which you shouldn’t be doing to begin with), isinstance is the preferred form anyhow, so neither == or is need be used.

    Feb 8, 2010 at 22:50

  • 25

    @Mike Graham, there are times when type is the best answer. There are times when isinstance is the best answer and there are times when duck typing is the best answer. It’s important to know all of the options so you can choose which is more appropriate for the situation.

    Feb 8, 2010 at 23:13

  • 6

    @gnibbler, That may be, though I haven’t yet ran into the situation where type(foo) is SomeType would be better than isinstance(foo, SomeType).

    Feb 9, 2010 at 16:45

  • 5

    @poke: i totally agree about PEP8, but you’re attacking a strawman here: the important part of Sven’s argument wasn’t PEP8, but that you can use isinstance for your usecase (checking for a range of types) as well, and with as clean a syntax as well, which has the great advantage that you can capture subclasses. someone using OrderedDict would hate your code to fail because it just accepts pure dicts.

    Oct 27, 2012 at 11:12

203

Use type():

>>> a = []
>>> type(a)
<type 'list'>
>>> f = ()
>>> type(f)
<type 'tuple'>

0

    44

    It might be more Pythonic to use a tryexcept block. That way, if you have a class which quacks like a list, or quacks like a dict, it will behave properly regardless of what its type really is.

    To clarify, the preferred method of “telling the difference” between variable types is with something called duck typing: as long as the methods (and return types) that a variable responds to are what your subroutine expects, treat it like what you expect it to be. For example, if you have a class that overloads the bracket operators with getattr and setattr, but uses some funny internal scheme, it would be appropriate for it to behave as a dictionary if that’s what it’s trying to emulate.

    The other problem with the type(A) is type(B) checking is that if A is a subclass of B, it evaluates to false when, programmatically, you would hope it would be true. If an object is a subclass of a list, it should work like a list: checking the type as presented in the other answer will prevent this. (isinstance will work, however).

    2

    • 16

      Duck typing isn’t really about telling the difference, though. It is about using a common interface.

      Nov 18, 2011 at 19:31

    • 6

      Be careful — most coding style guides recommend not using exception handling as part of the normal control flow of code, usually because it makes code difficult to read. tryexcept is a good solution when you want to deal with errors, but not when deciding on behavior based on type.

      Mar 12, 2016 at 12:02