How can I check if a Python object is a string (either regular or Unicode)?
-
18What Jason's referring to is duck typing (if it quacks like a duck it probably is a duck). In Python you often "let your code work" on any string-like object without testing whether it's a string or string subclass. For more info, see: http://docs.python.org/glossary.html#term-duck-typing – Ben Hoyt Aug 20 '09 at 00:12
-
5That's what I love about SO. I usually ask a question, it isn't answered, people tell me I shouldn't be doing that anyway and why, and I grow as a programmer. =) – physicsmichael Aug 20 '09 at 17:41
-
27+1: Just because an answer is rarely needed, doesn't mean the question is invalid. Although, I think it's great to have a caution here, I don't think it merits demoting the question. – Trevor Mar 08 '13 at 23:42
-
17This is possibly the most legitimate use of type checking in Python. Strings are iterable, so distinguishing them from lists any other way is a bad idea. – ojrac Mar 15 '13 at 19:07
-
3There are definitely cases where it is necessary to distinguish strings from other iterables. For example, see the source code for PrettyPrinter in the pprint module. – saxman01 Jun 10 '14 at 14:38
-
1I think duck typing is meant to work with polymorphism. Some people have a knee-jerk reaction against ALL python type checking. [Ben's link](http://docs.python.org/glossary.html#term-duck-typing) doesn't really speak against things where the types have fundamentally different behaviors. My interpretation is that duck typing is meant to trust the [Liskov Substitution Principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) – John Walthour May 06 '16 at 21:02
-
Strings are not only iterables, they are *iterables of strings*. Distinguishing them from other iterables of string without 'cheating' is almost impossible. But then there's [stringlike](https://pypi.python.org/pypi/stringlike) and the cheating code breaks. – clacke Jul 28 '16 at 12:34
-
Since lots of new people will probably read this: first be sure that you really do have to check. [My answer](https://stackoverflow.com/a/45228730/2437514) might give some ideas on how to avoid the check. – Rick Jul 21 '17 at 04:19
-
Also see https://stackoverflow.com/questions/4843173/how-to-check-if-type-of-a-variable-is-string – crizCraig Jul 09 '18 at 22:02
15 Answers

- 9,965
- 4
- 40
- 47

- 41,203
- 19
- 62
- 77
-
All solutions on this page are all non-fool-proof. I mean `basestring` and `str` can both be overwritten which will make all this solutions invalid. – Aug 03 '21 at 03:00
Python 3
In Python 3.x basestring
is not available anymore, as str
is the sole string type (with the semantics of Python 2.x's unicode
).
So the check in Python 3.x is just:
isinstance(obj_to_test, str)
This follows the fix of the official 2to3
conversion tool: converting basestring
to str
.
-
2This does not work for string like objects : isinstance(collections.UserString("foe"), str) == False – loutre Dec 22 '20 at 11:15
-
@loutre Thanks for your comment. I did not come across the User collections (`UserString`, `UserDict`, `UserList`) before. Those types already predate Python 2. As those types do not inherit from the build-in types `str`, `dict` or `list` the isinstance call will not work. FYI: Because of this it is not guaranteed that those types can be used as a drop-in replacement. E.g. the regex module `re` does not work with `UserString` (at least with Python 3.8.2). – Cwt Dec 23 '20 at 17:17
Python 2
To check if an object o
is a string type of a subclass of a string type:
isinstance(o, basestring)
because both str
and unicode
are subclasses of basestring
.
To check if the type of o
is exactly str
:
type(o) is str
To check if o
is an instance of str
or any subclass of str
:
isinstance(o, str)
The above also work for Unicode strings if you replace str
with unicode
.
However, you may not need to do explicit type checking at all. "Duck typing" may fit your needs. See http://docs.python.org/glossary.html#term-duck-typing.
See also What’s the canonical way to check for type in python?
-
-
@johnktejik python3 vs python2. You need to check for `basestring` in py2. – erikbstack Aug 29 '18 at 13:31
Python 2 and 3
(cross-compatible)
If you want to check with no regard for Python version (2.x vs 3.x), use six
(PyPI) and its string_types
attribute:
import six
if isinstance(obj, six.string_types):
print('obj is a string!')
Within six
(a very light-weight single-file module), it's simply doing this:
import sys
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str
else:
string_types = basestring

- 4,264
- 5
- 33
- 67

- 25,754
- 12
- 83
- 121
-
Alternatively, you can use [`future`](http://python-future.org/) ([PyPI](https://pypi.python.org/pypi/future/)) to even keep the name: `from past.builtins import basestring` – David Nemeskey Feb 08 '17 at 14:25
-
1BTW the [Cheat Sheet](http://python-future.org/compatible_idioms.html#basestring) is a great resource for Python version compatibility. – David Nemeskey Feb 08 '17 at 14:45
-
1What about not using any imports? First try `basestring` and then fall back to `str`. E.g. `def is_string(obj): try: return isinstance(obj, basestring) # python 2 except NameError: return isinstance(obj, str) # python 3 ` – isaacbernat Aug 13 '17 at 18:19
I found this ans more pythonic
:
if type(aObject) is str:
#do your stuff here
pass
since type objects are singleton, is can be used to do the compare the object to the str type

- 1
- 1

- 363
- 2
- 4
-
7This is not the general recommended way of testing for type, because of inheritance: `isinstance(obj_to_test, str)` is obviously meant to test for type, and it has the advantage of using the same procedure as for other, non-str cases. – Eric O. Lebigot Jun 17 '18 at 16:41
If one wants to stay away from explicit type-checking (and there are good reasons to stay away from it), probably the safest part of the string protocol to check is:
str(maybe_string) == maybe_string
It won't iterate through an iterable or iterator, it won't call a list-of-strings a string and it correctly detects a stringlike as a string.
Of course there are drawbacks. For example, str(maybe_string)
may be a heavy calculation. As so often, the answer is it depends.
EDIT: As @Tcll points out in the comments, the question actually asks for a way to detect both unicode strings and bytestrings. On Python 2 this answer will fail with an exception for unicode strings that contain non-ASCII characters, and on Python 3 it will return False
for all bytestrings.

- 7,688
- 6
- 46
- 48
-
In the case of objects that initialize with representation data, this may not work as expected... `b = b'test'; r = str(b) == b` where `b` holds the same data as `str(b)` but (being a bytes object) does not validate as a string. – Tcll Dec 06 '19 at 00:18
-
@Tcll Right, the question actually says "either regular or Unicode". I guess I didn't read it properly. – clacke Jan 04 '20 at 21:27
In order to check if your variable is something you could go like:
s='Hello World'
if isinstance(s,str):
#do something here,
The output of isistance will give you a boolean True or False value so you can adjust accordingly. You can check the expected acronym of your value by initially using: type(s) This will return you type 'str' so you can use it in the isistance function.

- 139
- 1
- 4
Its simple, use the following code (we assume the object mentioned to be obj)-
if type(obj) == str:
print('It is a string')
else:
print('It is not a string.')

- 363
- 2
- 14
I might deal with this in the duck-typing style, like others mention. How do I know a string is really a string? well, obviously by converting it to a string!
def myfunc(word):
word = unicode(word)
...
If the arg is already a string or unicode type, real_word will hold its value unmodified. If the object passed implements a __unicode__
method, that is used to get its unicode representation. If the object passed cannot be used as a string, the unicode
builtin raises an exception.

- 151,563
- 33
- 264
- 304
isinstance(your_object, basestring)
will be True if your object is indeed a string-type. 'str' is reserved word.
my apologies, the correct answer is using 'basestring' instead of 'str' in order of it to include unicode strings as well - as been noted above by one of the other responders.

- 51
- 6
-
Doesn't work for unicode objects, which were explicitly requested in the question. – dbn May 02 '14 at 19:31
This evening I ran into a situation in which I thought I was going to have to check against the str
type, but it turned out I did not.
My approach to solving the problem will probably work in many situations, so I offer it below in case others reading this question are interested (Python 3 only).
# NOTE: fields is an object that COULD be any number of things, including:
# - a single string-like object
# - a string-like object that needs to be converted to a sequence of
# string-like objects at some separator, sep
# - a sequence of string-like objects
def getfields(*fields, sep=' ', validator=lambda f: True):
'''Take a field sequence definition and yield from a validated
field sequence. Accepts a string, a string with separators,
or a sequence of strings'''
if fields:
try:
# single unpack in the case of a single argument
fieldseq, = fields
try:
# convert to string sequence if string
fieldseq = fieldseq.split(sep)
except AttributeError:
# not a string; assume other iterable
pass
except ValueError:
# not a single argument and not a string
fieldseq = fields
invalid_fields = [field for field in fieldseq if not validator(field)]
if invalid_fields:
raise ValueError('One or more field names is invalid:\n'
'{!r}'.format(invalid_fields))
else:
raise ValueError('No fields were provided')
try:
yield from fieldseq
except TypeError as e:
raise ValueError('Single field argument must be a string'
'or an interable') from e
Some tests:
from . import getfields
def test_getfields_novalidation():
result = ['a', 'b']
assert list(getfields('a b')) == result
assert list(getfields('a,b', sep=',')) == result
assert list(getfields('a', 'b')) == result
assert list(getfields(['a', 'b'])) == result

- 43,029
- 15
- 76
- 119
You can test it by concatenating with an empty string:
def is_string(s):
try:
s += ''
except:
return False
return True
Edit:
Correcting my answer after comments pointing out that this fails with lists
def is_string(s):
return isinstance(s, basestring)

- 1,927
- 3
- 20
- 24
I think it's safe to assume that if the final character of the output of repr()
is a '
or "
, then whatever it is, it aught to be considered some kind of string.
def isStr(o):
return repr(o)[-1] in '\'"'
I'm assuming that repr
won't be doing anything too heavy and that it'll return a string of at least one character. You can support empty strings by using something like
repr(o)[-1:].replace('"', "'") == "'"
but that's still assuming repr
returns a string at all.

- 20,617
- 19
- 137
- 193
if type(varA) == str or type(varB) == str:
print 'string involved'
from EDX - online course MITx: 6.00.1x Introduction to Computer Science and Programming Using Python

- 49,085
- 60
- 166
- 233

- 1
- 1
-
6This is probably the worst possible way to check. Not only does it exclude unicode objects, it even excludes subclasses of `str`! – augurar Dec 16 '14 at 22:23
For a nice duck-typing approach for string-likes that has the bonus of working with both Python 2.x and 3.x:
def is_string(obj):
try:
obj + ''
return True
except TypeError:
return False
wisefish was close with the duck-typing before he switched to the isinstance
approach, except that +=
has a different meaning for lists than +
does.

- 1
- 1

- 2,854
- 3
- 16
- 19
-
2Well, you have two downvotes and no one provided a comment. I've not downvoted but I don't like your solution because: * Too verbose. You shouldn't need to define a function to do this. * Expensive. Catching exceptions is not good for performance. * Error prone. Other object might implement __add__, see a string, and raise another type of exception, which is not TypeError. – santiagobasulto Dec 03 '15 at 17:59
-
Also here you are employing the duck-typing approach, which is beautiful, but end up with throwing and catching exception just to find out something, which is not beautiful. – Alexey Tigarev Jan 05 '16 at 20:07
-
This may be legitimately the only surefire way to distinguish between a string-like and some other iterable of string. One could look for attributes like `isalpha`, but who knows what methods would be safe to look for? – clacke Jul 28 '16 at 12:33
-
I [realized](http://stackoverflow.com/a/38636757/260122) that the `__str__` method plus equality may actually be the fool-proof one. But even that is not without caveats. – clacke Jul 28 '16 at 12:46
-
@santiagobasulto exceptions are cheap in Python. If you expect the error 1% of the time, `try` can be faster. If you expect it 99% of the time, maybe not. The performance difference being minimal, it's better to be idiomatic unless you profile your code and identify it as actually being slow. – Nick T Feb 08 '17 at 15:49