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 type
s 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
How to Turn Off Info Logging in Spark
Generate a Random Derangement of a List
Print All Day-Dates Between Two Dates
How to Use Selenium with Python
Search in Lists of Lists by Given Index
How to Add a Custom Ca Root Certificate to the Ca Store Used by Pip in Windows
Reference List Item by Index Within Django Template
Pandas Pivot Tables Row Subtotals
Python String 'Join' Is Faster () Than '+', But What's Wrong Here
Bin Elements Per Row - Vectorized 2D Bincount for Numpy
Python Request Post with Param Data