What Is the Best (Idiomatic) Way to Check the Type of a Python Variable

What is the best (idiomatic) way to check the type of a Python variable?

What happens if somebody passes a unicode string to your function? Or a class derived from dict? Or a class implementing a dict-like interface? Following code covers first two cases. If you are using Python 2.6 you might want to use collections.Mapping instead of dict as per the ABC PEP.

def value_list(x):
if isinstance(x, dict):
return list(set(x.values()))
elif isinstance(x, basestring):
return [x]
else:
return None

What is the best way to check if a variable is of numeric type in python

The easiest way to check if an object is a number is to do arithmethic operations (such as add 0) and see if we can get away with it:

def isnumeric(obj):
try:
obj + 0
return True
except TypeError:
return False

print isnumeric([1,2,3]) # False
print isnumeric(2.5) # True
print isnumeric('25') # False

What's the canonical way to check for type in Python?

Use isinstance to check if o is an instance of str or any subclass of str:

if isinstance(o, str):

To check if the type of o is exactly str, excluding subclasses of str:

if type(o) is str:

Another alternative to the above:

if issubclass(type(o), str):

See Built-in Functions in the Python Library Reference for relevant information.



Checking for strings in Python 2

For Python 2, this is a better way to check if o is a string:

if isinstance(o, basestring):

because this will also catch Unicode strings. unicode is not a subclass of str; whereas, both str and unicode are subclasses of basestring. In Python 3, basestring no longer exists since there's a strict separation of strings (str) and binary data (bytes).

Alternatively, isinstance accepts a tuple of classes. This will return True if o is an instance of any subclass of any of (str, unicode):

if isinstance(o, (str, unicode)):

How to check if a variable is a dictionary in Python?

You could use if type(ele) is dict or use isinstance(ele, dict) which would work if you had subclassed dict:

d = {'abc': 'abc', 'def': {'ghi': 'ghi', 'jkl': 'jkl'}}
for element in d.values():
if isinstance(element, dict):
for k, v in element.items():
print(k,' ',v)

What are the differences between type() and isinstance()?

To summarize the contents of other (already good!) answers, isinstance caters for inheritance (an instance of a derived class is an instance of a base class, too), while checking for equality of type does not (it demands identity of types and rejects instances of subtypes, AKA subclasses).

Normally, in Python, you want your code to support inheritance, of course (since inheritance is so handy, it would be bad to stop code using yours from using it!), so isinstance is less bad than checking identity of types because it seamlessly supports inheritance.

It's not that isinstance is good, mind you—it's just less bad than checking equality of types. The normal, Pythonic, preferred solution is almost invariably "duck typing": try using the argument as if it was of a certain desired type, do it in a try/except statement catching all exceptions that could arise if the argument was not in fact of that type (or any other type nicely duck-mimicking it;-), and in the except clause, try something else (using the argument "as if" it was of some other type).

basestring is, however, quite a special case—a builtin type that exists only to let you use isinstance (both str and unicode subclass basestring). Strings are sequences (you could loop over them, index them, slice them, ...), but you generally want to treat them as "scalar" types—it's somewhat incovenient (but a reasonably frequent use case) to treat all kinds of strings (and maybe other scalar types, i.e., ones you can't loop on) one way, all containers (lists, sets, dicts, ...) in another way, and basestring plus isinstance helps you do that—the overall structure of this idiom is something like:

if isinstance(x, basestring)
return treatasscalar(x)
try:
return treatasiter(iter(x))
except TypeError:
return treatasscalar(x)

You could say that basestring is an Abstract Base Class ("ABC")—it offers no concrete functionality to subclasses, but rather exists as a "marker", mainly for use with isinstance. The concept is obviously a growing one in Python, since PEP 3119, which introduces a generalization of it, was accepted and has been implemented starting with Python 2.6 and 3.0.

The PEP makes it clear that, while ABCs can often substitute for duck typing, there is generally no big pressure to do that (see here). ABCs as implemented in recent Python versions do however offer extra goodies: isinstance (and issubclass) can now mean more than just "[an instance of] a derived class" (in particular, any class can be "registered" with an ABC so that it will show as a subclass, and its instances as instances of the ABC); and ABCs can also offer extra convenience to actual subclasses in a very natural way via Template Method design pattern applications (see here and here [[part II]] for more on the TM DP, in general and specifically in Python, independent of ABCs).

For the underlying mechanics of ABC support as offered in Python 2.6, see here; for their 3.1 version, very similar, see here. In both versions, standard library module collections (that's the 3.1 version—for the very similar 2.6 version, see here) offers several useful ABCs.

For the purpose of this answer, the key thing to retain about ABCs (beyond an arguably more natural placement for TM DP functionality, compared to the classic Python alternative of mixin classes such as UserDict.DictMixin) is that they make isinstance (and issubclass) much more attractive and pervasive (in Python 2.6 and going forward) than they used to be (in 2.5 and before), and therefore, by contrast, make checking type equality an even worse practice in recent Python versions than it already used to be.

How do you set a conditional in python based on datatypes?

How about,

if isinstance(x, int):

but a cleaner way would simply be

sum(z for z in y if isinstance(z, int))

How can I type-check variables in Python?

isinstance(n, int)

If you need to know whether it's definitely an actual int and not a subclass of int (generally you shouldn't need to do this):

type(n) is int

this:

return int(n) == n

isn't such a good idea, as cross-type comparisons can be true - notably int(3.0)==3.0

Type checking of arguments Python

Use isinstance(). Sample:

if isinstance(n, unicode):
# do this
elif isinstance(n, Node):
# do that
...

not None test in Python

if val is not None:
# ...

is the Pythonic idiom for testing that a variable is not set to None. This idiom has particular uses in the case of declaring keyword functions with default parameters. is tests identity in Python. Because there is one and only one instance of None present in a running Python script/program, is is the optimal test for this. As Johnsyweb points out, this is discussed in PEP 8 under "Programming Recommendations".

As for why this is preferred to

if not (val is None):
# ...

this is simply part of the Zen of Python: "Readability counts." Good Python is often close to good pseudocode.



Related Topics



Leave a reply



Submit