DEV Community

Alexandre Plt
Alexandre Plt

Posted on • Edited on

9 2

Call me maybe - an explanations of Python callables

If you have some experience with Python, you must have already seen a TypeError: 'T' object is not callable.

In this article we will try to demystify this kind of errors.

What is a callable?

A callable is anything that can be called, from a function, to a class constructor.

For example, len is a callable because we can write len(object).

Creating a callable

The easiest way is to write a function or a lambda:

def foo(*args):
    pass

bar = lambda *args: 0
Enter fullscreen mode Exit fullscreen mode

But here we won't cover those things as they are basic Python knowledge.

class Foo:
    def __call__(self, *args):
        print("hello world!")

bar = Foo()  # instanciating a Foo object, creating a callable
bar()  # calling it!
Enter fullscreen mode Exit fullscreen mode

We created a basic callable by giving it a __call__ method, and we can check if an object is callable (useful when debugging) by using:

# homemade method to explain EAFP
def is_callable(obj, *args, **kwargs, ***okwargs):
    try:
        obj(*args, **kwargs, ***okwargs)
    except TypeError as e:
        return 'object is not callable' not in str(e)
    return True

# built-in way to check if an object is callable (thanks rhymes for pointing it out): using callable(obj)
>>> callable(foo), callable(bar), callable(Foo), callable(Foo()), callable(3)
(True, True, True, True, False)
Enter fullscreen mode Exit fullscreen mode

Because we can't use hasattr(obj, '__call__'), since Python is skipping __getattribute__ and __getattr__ when calling something, thus we can only do what's called EAFP: Easier to ask for forgiveness than permission.


Hopefully this article has helped you, if you have anything to add feel free to leave a comment!

Originally from lexp.lt

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Top comments (2)

Collapse
 
rhymes profile image
rhymes • Edited

Hi Alexandre, nice intro to callable.

Python definitely leans on EAFP over LBYL as you know :)

A tip: there's an easier way to check if something is a callable that requires zero lines of custom code. The builtin callable() function.

>>> def foo(*args):
...     pass
...
>>> bar = lambda *args: 0
>>> class Foo:
...     def __call__(self, *args):
...         print("hello world!")
...
>>> callable(foo), callable(bar), callable(Foo), callable(Foo()), callable(3)
(True, True, True, True, False)

hope this helps! :-)

Collapse
 
lexplt profile image
Alexandre Plt

Hi!
Thanks for the tip, I had forgotten that this existed :/

I'll add that :)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more