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

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

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 :)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay