8

I've seen people often recommend using isinstance() instead of type(), which I find odd because type() seems more readable to me.

>>> isinstance("String",str)
True
>>> type("String") is str
True

The latter seems more pythonic and clear while the former is slightly obfuscated and implies a specific use to me (for example, testing user built classes rather than built in types) but is there some other benefit that I'm unaware of? Does type() cause some erratic behaviour or miss some comparisons?

SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73
  • I remember the document has explained why it should use `isinstance`. I need time to find. – Burger King May 05 '15 at 09:47
  • 1
    `polymorphish` is a keyword to look up if you want to know more. – Łukasz Rogalski May 05 '15 at 09:50
  • 2
    Note that the most Pythonic approach is to treat it as if it *was* a string (or something more general, e.g. a sequence), and (optionally) recover from errors where it isn't. I occasionally use `isinstance(whatever, basestr)` where I *need* to treat strings differently from other sequences, but otherwise does it matter? – jonrsharpe May 05 '15 at 10:08

4 Answers4

14

Let me give you a simple example why they can be different:

>>> class A(object): pass
>>> class B(A) : pass
>>> a = A()
>>> b = B()

So far, declared a variable A and a variable B derived from A.

>>> isinstance(a, A)
True
>>> type(a) == A
True

BUT

>>> isinstance(b, A)
True
>>> type(b) == A
False
rafaelc
  • 57,686
  • 15
  • 58
  • 82
2

You are precluding the possibility to use subclasses here.

Why limit yourself to just the one type when a subclass would satisfy the interface? If someone wants to use class mystr(str): ... for something, your code would still work and doesn't need to know that a subclass was used.

As such, using isinstance() is the more pythonic approach; your code should look for supported behaviours, not specific types.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

Basic example for Python 2.x: Standard strings and unicode strings, with common base class basestring:

s = "123"
u = u"123"
isinstance(s, str) is True
type(u) == str  # something which has string nature returns False for this test
# these tests are common-pattern in Python 2.x and behaves correctly
isinstance(s, basestring) is True
isinstance(u, basestring) is True
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
1

Here is the counter-example:

class A():
    pass

a = A()

>>> isinstance(a, A)
True
>>> type(a) is A
False

Thus I consider isinstance as a more generic one.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
mateusz.b
  • 103
  • 1
  • 7
  • 1
    Note that this only happens if `A` is an old-style class; with a new-style class (all classes in 3.x, classes inheriting from `object` in 2.x) `type(a) is A`. – jonrsharpe May 05 '15 at 09:55