python - Determine the type of an object?

ID : 454

viewed : 179

Tags : pythondictionarytypestypeofpython

Top 5 Answer for python - Determine the type of an object?

vote vote

98

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 
vote vote

88

You can do that using type():

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

74

It might be more Pythonic to use a try...except 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).

vote vote

61

On instances of object you also have the:

__class__ 

attribute. Here is a sample taken from Python 3.3 console

>>> str = "str" >>> str.__class__ <class 'str'> >>> i = 2 >>> i.__class__ <class 'int'> >>> class Test(): ...     pass ... >>> a = Test() >>> a.__class__ <class '__main__.Test'> 

Beware that in python 3.x and in New-Style classes (aviable optionally from Python 2.6) class and type have been merged and this can sometime lead to unexpected results. Mainly for this reason my favorite way of testing types/classes is to the isinstance built in function.

vote vote

57

Determine the type of a Python object

Determine the type of an object with type

>>> obj = object() >>> type(obj) <class 'object'> 

Although it works, avoid double underscore attributes like __class__ - they're not semantically public, and, while perhaps not in this case, the builtin functions usually have better behavior.

>>> obj.__class__ # avoid this! <class 'object'> 

type checking

Is there a simple way to determine if a variable is a list, dictionary, or something else? I am getting an object back that may be either type and I need to be able to tell the difference.

Well that's a different question, don't use type - use isinstance:

def foo(obj):     """given a string with items separated by spaces,      or a list or tuple,      do something sensible     """     if isinstance(obj, str):         obj = str.split()     return _foo_handles_only_lists_or_tuples(obj) 

This covers the case where your user might be doing something clever or sensible by subclassing str - according to the principle of Liskov Substitution, you want to be able to use subclass instances without breaking your code - and isinstance supports this.

Use Abstractions

Even better, you might look for a specific Abstract Base Class from collections or numbers:

from collections import Iterable from numbers import Number  def bar(obj):     """does something sensible with an iterable of numbers,      or just one number     """     if isinstance(obj, Number): # make it a 1-tuple         obj = (obj,)     if not isinstance(obj, Iterable):         raise TypeError('obj must be either a number or iterable of numbers')     return _bar_sensible_with_iterable(obj) 

Or Just Don't explicitly Type-check

Or, perhaps best of all, use duck-typing, and don't explicitly type-check your code. Duck-typing supports Liskov Substitution with more elegance and less verbosity.

def baz(obj):     """given an obj, a dict (or anything with an .items method)      do something sensible with each key-value pair     """     for key, value in obj.items():         _baz_something_sensible(key, value) 

Conclusion

  • Use type to actually get an instance's class.
  • Use isinstance to explicitly check for actual subclasses or registered abstractions.
  • And just avoid type-checking where it makes sense.

Top 3 video Explaining python - Determine the type of an object?

Related QUESTION?