1

Is there a good one-stop-shop Python reference for choosing attributes to use with hasattr() to identify types.

For example, the following is for a sequence which is not a string:

def is_sequence(arg):
    return (not hasattr(arg, "strip") and
            hasattr(arg, "__getitem__") or
            hasattr(arg, "__iter__")) 

It would be nice to have a solid reference for choosing the best patterns quickly.

Michael Allan Jackson
  • 4,217
  • 3
  • 35
  • 45

2 Answers2

5

Use the virtual subclasses that have already been written for you in the collections module (collections.abc in Python 3.3).

To check if something is a non-string sequence, use

from collections import Sequence    # collections.abc in Python 3.3
isinstance(arg, Sequence) and not isinstance(arg, basestring)    # str in Python 3
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • I was using isinstance regularly but I continued to read it is more "Pythonic" to use hasattr so that we don't unnecessarily exclude objects that have the proper methods and would otherwise work. – Michael Allan Jackson Sep 18 '12 at 16:52
  • 1
    @majgis -- Really, the you can just `try` to use the object, and if you get an `AttributeError`, apparently it didn't work. You *could* check if the object has all of the attributes that you're going to use using `hasattr`, however, `isinstance` exists for those rare times when you want to make sure you're working with a list and not something else. Don't be afraid to use `isinstance` if you *need* a specific type. However, you don't usually *need* a specific type, and you rarely need to check ahead of time because of `try`/`except` – mgilson Sep 18 '12 at 16:56
  • 3
    @majgis that advice predates the existence of virtual subclasses. Note that the *most* Pythonic code still tends to use `try`/`except`. – ecatmur Sep 18 '12 at 17:00
1

Use the appropriate abstract base class:

import collections
isinstance([], collections.Sequence) # ==> true
nneonneo
  • 171,345
  • 36
  • 312
  • 383