12

I looked at this thread but some of the concepts are above my current level. In Python 2.x, the callable() built-in method exists; is there a simple way to check to see if something is callable or not using Python 3?

Community
  • 1
  • 1
Sophia
  • 155
  • 1
  • 6

3 Answers3

40

It's back. Python 3.2 has callable(); there is no longer a need to use one of the less convenient alternatives.

joeforker
  • 40,459
  • 37
  • 151
  • 246
18

callable() is back in Python 3.2.

If you need to use Python 3.1 (highly unlikely) then in addition to checking for __call__ there are also the following solutions:

  • 2to3 changes a callable(x) into isinstance(x, collections.Callable)

  • six uses

      any("__call__" in klass.__dict__ for klass in type(x).__mro__)
    

    Ie it checks for __call__ in the base classes. This reminds me that I should ask Benjamin why. :)

And lastly you can of course simply try:

try:
    x = x()
except TypeError:
    pass
Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • Great 2to3 reference... that is a convincing argument for using `collections.Callable`. ABCs are everywhere now, it seems. – Russ Nov 03 '11 at 04:23
  • 7
    Brilliant. But try/except advice is scary. – Shekhar Nov 10 '11 at 18:16
  • @Shekhar: exception handling is not scary once you're used to it. – Lennart Regebro Nov 12 '11 at 10:20
  • @LennartRegebro That was about calling to check if object in question is callable or not. Some of my code is sensitive to that. It wasn't about try/except really. Hope my comment is more clear now. – Shekhar Nov 13 '11 at 16:54
  • @Shekhar: No, quite the opposite in fact. try/except's are not scary, and they are relevant to code that is sensitive to if something is callable or not. A try/except is a very pythonic way of handling that. – Lennart Regebro Nov 13 '11 at 22:06
  • 1
    @LennartRegebro It's not about try/except :). It's about executing x to see if x is callable. try: explode() except: pass – Shekhar Nov 14 '11 at 09:31
  • 2
    @LennartRegebro Sorry for taking it too long but I don't agree. I have few callables in my code (__call__ with more than few lines of code, has a few db calls and changes object states sometimes). I may not prefer to call these to see if they are callable. – Shekhar Nov 14 '11 at 12:48
  • @Shekhar: No, maybe I'm unclear. The point is not to call it to see if it are callable. The point is that you just do whatever you would as if it was callable. **You don't need to check at all**. If calling it raises a type error then you do whatever you do if they aren't callable. This is known as "EAFP", as opposed to what you are doing which is called "LBYL", which is considered unpythonic. See http://sayspy.blogspot.com/2008/12/why-explicit-type-checking-is-mostly.html – Lennart Regebro Nov 14 '11 at 15:02
  • 4
    This is an old-ish conversation, but I should note: What happens if ``x`` itself attempts to call something and doesn't catch its the resulting TypeError exception? Then you haven't determined that ``x`` isn't callable, but rather that some call-chain within ``x`` threw a TypeError. Subtly different, but different. – twooster Mar 10 '12 at 03:58
  • 1
    The advantage of using the `isinstance(x, collections.Callable)` check is that `ABCMeta.__subclasscheck__` caches its calls. – forivall Mar 21 '13 at 18:45
  • 1
    @LennartRegebro: I think that EAFP is good in general but not for this specific case. If x is callable but the function called raises a TypeError then this would be caught wrongly as not callable. – olivecoder Oct 28 '15 at 12:30
9

You can just do hasattr(object_name, '__call__') instead. Unlike in Python 2.x, this works for all callable objects, including classes.

Chinmay Kanchi
  • 62,729
  • 22
  • 87
  • 114
  • 2
    In Python 2.x, it works for new-style classes but not old-style. Remember, though, the `__call__` called on a (new-style) class is `type`'s (or the class's metaclass's), not the class's. – kindall Dec 08 '10 at 01:50
  • @kindall: Good point, worth keeping in mind. Though of course, it would be rather strange if it were any different. This also allows you to do funky things like `class_name()()` – Chinmay Kanchi Dec 08 '10 at 01:53
  • Please be aware that this will give a false positive in the following corner-case: `class C(object): pass; c = C(); c.__call__ = lambda self: None`. Even though `c` now has a function as the __call__ attribute, `c()` will fail, even though the `hasattr` check will succeed. I'm not sure but I cannot rule out a false-negative corner-case possible too, though if possible it would probably require implemented-in-C-code objects to trigger it. – mtraceur Feb 01 '18 at 02:08