How to check if variable is string with python 2 and 3 compatibility

Question:

I’m aware that I can use: isinstance(x, str) in python-3.x but I need to check if something is a string in python-2.x as well. Will isinstance(x, str) work as expected in python-2.x? Or will I need to check the version and use isinstance(x, basestr)?

Specifically, in python-2.x:

>>>isinstance(u"test", str)
False

and python-3.x does not have u"foo"

Asked By: Randall Hunt

||

Answers:

Maybe use a workaround like

def isstr(s):
    try:
        return isinstance(s, basestring)
    except NameError:
        return isinstance(s, str)
Answered By: Lev Levitsky

If you’re writing 2.x-and-3.x-compatible code, you’ll probably want to use six:

from six import string_types
isinstance(s, string_types)
Answered By: ecatmur

This is @Lev Levitsky’s answer, re-written a bit.

try:
    isinstance("", basestring)
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

The try/except test is done once, and then defines a function that always works and is as fast as possible.

EDIT: Actually, we don’t even need to call isinstance(); we just need to evaluate basestring and see if we get a NameError:

try:
    basestring  # attempt to evaluate basestring
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

I think it is easier to follow with the call to isinstance(), though.

Answered By: steveha

You can get the class of an object by calling object.__class__, so in order to check if object is the default string type:

    isinstance(object,"".__class__)

And You can place the following in the top of Your code so that strings enclosed by quotes are in unicode in python 2:

    from __future__ import unicode_literals
Answered By: Martin Hansen

The most terse approach I’ve found without relying on packages like six, is:

try:
  basestring
except NameError:
  basestring = str

then, assuming you’ve been checking for strings in Python 2 in the most generic manner,

isinstance(s, basestring)

will now also work for Python 3+.

Answered By: hbristow

What about this, works in all cases?

isinstance(x, ("".__class__, u"".__class__))
Answered By: Fil

type(string) == str

returns true if its a string, and false if not

The future library adds (to Python 2) compatible names, so you can continue writing Python 3. You can simple do the following:

from builtins import str
isinstance(x, str) 

To install it, just execute pip install future.

As a caveat, it only support python>=2.6,>=3.3, but it is more modern than six, which is only recommended if using python 2.5

Answered By: toto_tico

You can try this at the beginning of your code:

from __future__ import print_function
import sys
if sys.version[0] == "2":
    py3 = False
else:
    py3 = True
if py3: 
    basstring = str
else:
    basstring = basestring

and later in the code:

anystring = "test"
# anystring = 1
if isinstance(anystring, basstring):
    print("This is a string")
else:
    print("No string")
Answered By: bunkus

Be careful! In python 2, str and bytes are essentially the same. This can cause a bug if you are trying to distinguish between the two.

>>> size = 5    
>>> byte_arr = bytes(size)
>>> isinstance(byte_arr, bytes)
True
>>> isinstance(byte_arr, str)
True
Answered By: Fardin Abdi