177

I know that __call__ method in a class is triggered when the instance of a class is called. However, I have no idea when I can use this special method, because one can simply create a new method and perform the same operation done in __call__ method and instead of calling the instance, you can call the method.

I would really appreciate it if someone gives me a practical usage of this special method.

Eric
  • 95,302
  • 53
  • 242
  • 374
mohi666
  • 6,842
  • 9
  • 45
  • 51
  • 2
    related: http://stackoverflow.com/questions/111234/what-is-a-callable-in-python/115349#115349 – jfs Apr 28 '11 at 21:20
  • 9
    the functionality of **__call__** is just like **the overloaded operator of () in C++**. If you simply create a new method outside of the class, you may not access the internal data in a class. – andy Mar 13 '14 at 04:45
  • 4
    The most common use of `__call__` is hidden in plain view; it's how you instantiate a class: `x = Foo()` is really `x = type(Foo).__call__(Foo)`, where `__call__` is defined by the metaclass of `Foo`. – chepner Jan 27 '19 at 17:02

16 Answers16

136

This example uses memoization, basically storing values in a table (dictionary in this case) so you can look them up later instead of recalculating them.

Here we use a simple class with a __call__ method to calculate factorials (through a callable object) instead of a factorial function that contains a static variable (as that's not possible in Python).

class Factorial:
    def __init__(self):
        self.cache = {}
    def __call__(self, n):
        if n not in self.cache:
            if n == 0:
                self.cache[n] = 1
            else:
                self.cache[n] = n * self.__call__(n-1)
        return self.cache[n]

fact = Factorial()

Now you have a fact object which is callable, just like every other function. For example

for i in xrange(10):                                                             
    print("{}! = {}".format(i, fact(i)))

# output
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880

And it is also stateful.

Community
  • 1
  • 1
S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 2
    I'd rather have a `fact` object that is indexable since your `__call__` function is essentially an index. Also would use a list instead of a dict, but that's just me. – Chris Lutz Apr 28 '11 at 20:59
  • This can be done with closures as well (and that wouldn't be one of the cases of "oh, X and Y are theoretically equivalent, let's go out of our way to emulate one with the other when it doesn't make the slightest sense" scenarios, the code would be even shorter and, arguably, more readable). –  Apr 28 '11 at 21:01
  • 4
    @delnan - Almost anything can be done several distinct ways. Which one's more readable depends on the reader. – Chris Lutz Apr 28 '11 at 21:04
  • 1
    @Chris Lutz: You're free to contemplate those kinds of changes. For memoization **in general**, a dictionary works out well because you can't guarantee the order in which things fill up your list. In this case, a list might work, but it's not going to be any faster or simpler. – S.Lott Apr 28 '11 at 21:05
  • 10
    @delnan: This is not intended to be shortest. No one wins at code golf. It's intended to show `__call__`, be simple and nothing more. – S.Lott Apr 28 '11 at 21:06
  • 3
    But it kind of ruins the example when the demonstrated technique isn't ideal for the tasks, doesn't it? (And I wasn't about the "let's save lines for the heck of it"-short, I was talking about the "write it in this equally clear manner and save some boilerplate code"-short. Rest assured that I'm not one of those madmen trying to write the shortest code possible, I merely want to avoid boilerplate code that adds nothing for the reader.) –  Apr 28 '11 at 21:07
  • 1
    @delnan: Please include code in your answer to make your point clearer. – S.Lott Apr 28 '11 at 21:17
  • That is a helpful explanation. – BO KANG Apr 16 '15 at 15:38
  • @S.Lott, this helped me understand this concept! Thanks! +1 – FearlessFuture Jun 18 '15 at 19:47
92

Django forms module uses __call__ method nicely to implement a consistent API for form validation. You can write your own validator for a form in Django as a function.

def custom_validator(value):
    #your validation logic

Django has some default built-in validators such as email validators, url validators etc., which broadly fall under the umbrella of RegEx validators. To implement these cleanly, Django resorts to callable classes (instead of functions). It implements default Regex Validation logic in a RegexValidator and then extends these classes for other validations.

class RegexValidator(object):
    def __call__(self, value):
        # validation logic

class URLValidator(RegexValidator):
    def __call__(self, value):
        super(URLValidator, self).__call__(value)
        #additional logic

class EmailValidator(RegexValidator):
    # some logic

Now both your custom function and built-in EmailValidator can be called with the same syntax.

for v in [custom_validator, EmailValidator()]:
    v(value) # <-----

As you can see, this implementation in Django is similar to what others have explained in their answers below. Can this be implemented in any other way? You could, but IMHO it will not be as readable or as easily extensible for a big framework like Django.

Praveen Gollakota
  • 37,112
  • 11
  • 62
  • 61
  • 5
    So if used correctly, it can make the code more readable. I assume if it is used on the wrong place, it would make the code very unreadable as well. – mohi666 Apr 29 '11 at 00:19
  • 17
    This is *an* example of how it can be used, but not a good one in my opinion. There's no advantage in this case to having a callable instance. It would be better to have an interface/abstract class with a method, like .validate(); it's the same thing only more explicit. The real value of \_\_call__ is being able to use an instance in a place where a callable is expected. I use \_\_call__ most often when creating decorators, for example. – Daniel Oct 01 '13 at 09:24
  • @Daniel Your last two sentences would make for a pretty nice answer to OP's question. Thanks! – joba2ca Oct 27 '22 at 12:36
41

I find it useful because it allows me to create APIs that are easy to use (you have some callable object that requires some specific arguments), and are easy to implement because you can use Object Oriented practices.

The following is code I wrote yesterday that makes a version of the hashlib.foo methods that hash entire files rather than strings:

# filehash.py
import hashlib


class Hasher(object):
    """
    A wrapper around the hashlib hash algorithms that allows an entire file to
    be hashed in a chunked manner.
    """
    def __init__(self, algorithm):
        self.algorithm = algorithm

    def __call__(self, file):
        hash = self.algorithm()
        with open(file, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), ''):
                hash.update(chunk)
        return hash.hexdigest()


md5    = Hasher(hashlib.md5)
sha1   = Hasher(hashlib.sha1)
sha224 = Hasher(hashlib.sha224)
sha256 = Hasher(hashlib.sha256)
sha384 = Hasher(hashlib.sha384)
sha512 = Hasher(hashlib.sha512)

This implementation allows me to use the functions in a similar fashion to the hashlib.foo functions:

from filehash import sha1
print sha1('somefile.txt')

Of course I could have implemented it a different way, but in this case it seemed like a simple approach.

bradley.ayers
  • 37,165
  • 14
  • 93
  • 99
  • 7
    Again, closures ruin this example. http://pastebin.com/961vU0ay is 80% the lines and just as clear. –  Apr 28 '11 at 21:13
  • 8
    I'm not convinced it would always be *just as clear* to someone (e.g. perhaps someone who has only used Java). Nested functions and variable lookup/scope might be confusing. I suppose my point was that `__call__` gives you a tool that lets you use OO techniques to solve problems. – bradley.ayers Apr 28 '11 at 21:18
  • 1
    Well, OP specifically asked why we should create a class with `__call__`, instead of e.g. using a different method name. Or (not mentioned in the question but the same question) why not use closures. (And on a side note, if someone's using Python and doesn't know closures, they should learn about them. I write code to be readable to people who know the language, and closures are a pretty fundamental concept, hardly exotic.) –  Apr 28 '11 at 21:20
  • 4
    I think the question "why use X over Y" when both provide equivalent functionality is terribly subjective. For some people the OO approach is easier to understand, for others the closure approach is. There's no compelling argument to use one over the other, unless you had a situation where you *had* to use ``isinstance`` or something similar. – bradley.ayers Apr 28 '11 at 21:26
  • 2
    @delnan Your closures example is less lines of code, but that it's just as clear is more difficult to argue. – Dennis Feb 21 '13 at 18:53
  • 13
    An example of where you would rather use a `__call__` method instead of a closure is when you're dealing with the multiprocessing module, which uses pickling to pass information between processes. You can't pickle a closure, but you can pickle an instance of a class. – John Thompson Apr 04 '13 at 14:55
  • 2
    The closure approach also forfeits all the benefits of inheritance. – twneale Feb 21 '14 at 04:11
38

__call__ is also used to implement decorator classes in python. In this case the instance of the class is called when the method with the decorator is called.

class EnterExitParam(object):

    def __init__(self, p1):
        self.p1 = p1

    def __call__(self, f):
        def new_f():
            print("Entering", f.__name__)
            print("p1=", self.p1)
            f()
            print("Leaving", f.__name__)
        return new_f


@EnterExitParam("foo bar")
def hello():
    print("Hello")


if __name__ == "__main__":
    hello()

program output:

Entering hello
p1= foo bar
Hello
Leaving hello
Daniel E
  • 394
  • 3
  • 13
Kris
  • 956
  • 1
  • 12
  • 23
11

Yes, when you know you're dealing with objects, it's perfectly possible (and in many cases advisable) to use an explicit method call. However, sometimes you deal with code that expects callable objects - typically functions, but thanks to __call__ you can build more complex objects, with instance data and more methods to delegate repetitive tasks, etc. that are still callable.

Also, sometimes you're using both objects for complex tasks (where it makes sense to write a dedicated class) and objects for simple tasks (that already exist in functions, or are more easily written as functions). To have a common interface, you either have to write tiny classes wrapping those functions with the expected interface, or you keep the functions functions and make the more complex objects callable. Let's take threads as example. The Thread objects from the standard libary module threading want a callable as target argument (i.e. as action to be done in the new thread). With a callable object, you are not restricted to functions, you can pass other objects as well, such as a relatively complex worker that gets tasks to do from other threads and executes them sequentially:

class Worker(object):
    def __init__(self, *args, **kwargs):
        self.queue = queue.Queue()
        self.args = args
        self.kwargs = kwargs

    def add_task(self, task):
        self.queue.put(task)

    def __call__(self):
        while True:
            next_action = self.queue.get()
            success = next_action(*self.args, **self.kwargs)
            if not success:
               self.add_task(next_action)

This is just an example off the top of my head, but I think it is already complex enough to warrant the class. Doing this only with functions is hard, at least it requires returning two functions and that's slowly getting complex. One could rename __call__ to something else and pass a bound method, but that makes the code creating the thread slightly less obvious, and doesn't add any value.

yann.kmm
  • 827
  • 7
  • 21
  • 3
    It's probably useful to use the phrase "duck typing" (http://en.wikipedia.org/wiki/Duck_typing#In_Python) here -- you can *mimic* a function using a more complicated class object this way. – Andrew Jaffe Apr 28 '11 at 21:19
  • 2
    As a related example, I've seen `__call__` used to use class instances (instead of functions) as WSGI applications. Here's an example from "The Definitive Guide to Pylons": [Using Instances of Classes](http://pylonsbook.com/en/1.1/the-web-server-gateway-interface-wsgi.html#using-instances-of-classes) – Josh Rosen Apr 29 '11 at 00:48
5

Class-based decorators use __call__ to reference the wrapped function. E.g.:

class Deco(object):
    def __init__(self,f):
        self.f = f
    def __call__(self, *args, **kwargs):
        print args
        print kwargs
        self.f(*args, **kwargs)

There is a good description of the various options here at Artima.com

rorycl
  • 1,344
  • 11
  • 19
  • I rarely see class decorators though, as they require some nonobvious boilerplate code to work with methods. –  Apr 28 '11 at 21:15
4

IMHO __call__ method and closures give us a natural way to create STRATEGY design pattern in Python. We define a family of algorithms, encapsulate each one, make them interchangeable and in the end we can execute a common set of steps and, for example, calculate a hash for a file.

ady
  • 1,108
  • 13
  • 19
4

I just stumbled upon a usage of __call__() in concert with __getattr__() which I think is beautiful. It allows you to hide multiple levels of a JSON/HTTP/(however_serialized) API inside an object.

The __getattr__() part takes care of iteratively returning a modified instance of the same class, filling in one more attribute at a time. Then, after all information has been exhausted, __call__() takes over with whatever arguments you passed in.

Using this model, you can for example make a call like api.v2.volumes.ssd.update(size=20), which ends up in a PUT request to https://some.tld/api/v2/volumes/ssd/update.

The particular code is a block storage driver for a certain volume backend in OpenStack, you can check it out here: https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/nexenta/jsonrpc.py

EDIT: Updated the link to point to master revision.

  • That's nice. I once used the same mechanism for traversing an arbitrary XML tree using attribute access. – Petri Oct 24 '16 at 04:45
2

I find a good place to use callable objects, those that define __call__(), is when using the functional programming capabilities in Python, such as map(), filter(), reduce().

The best time to use a callable object over a plain function or a lambda function is when the logic is complex and needs to retain some state or uses other info that in not passed to the __call__() function.

Here's some code that filters file names based upon their filename extension using a callable object and filter().

Callable:

import os

class FileAcceptor(object):
    def __init__(self, accepted_extensions):
        self.accepted_extensions = accepted_extensions

    def __call__(self, filename):
        base, ext = os.path.splitext(filename)
        return ext in self.accepted_extensions

class ImageFileAcceptor(FileAcceptor):
    def __init__(self):
        image_extensions = ('.jpg', '.jpeg', '.gif', '.bmp')
        super(ImageFileAcceptor, self).__init__(image_extensions)

Usage:

filenames = [
    'me.jpg',
    'me.txt',
    'friend1.jpg',
    'friend2.bmp',
    'you.jpeg',
    'you.xml']

acceptor = ImageFileAcceptor()
image_filenames = filter(acceptor, filenames)
print image_filenames

Output:

['me.jpg', 'friend1.jpg', 'friend2.bmp', 'you.jpeg']
cycgrog
  • 21
  • 3
2

I'm a novice, but here is my take: having __call__ makes composition easier to code. If f, g are instance of a class Function that has a method eval(self,x), then with __call___ one could write f(g(x)) as opposed to f.eval(g.eval(x)).

A neural network can be composed from smaller neural networks, and in pytorch we have a __call__ in the Module class:

Here's an example of where __call__ is used in practice: in pytorch, when defining a neural network (call it class MyNN(nn.Module) for example) as a subclass of torch.nn.module.Module, one typically defines a forward method for the class, but typically when applying an input tensor x to an instance model=MyNN() we just write model(x) as opposed to model.forward(x) but both give the same answer. If you dig into the source for torch.nn.module.Module here

https://pytorch.org/docs/stable/_modules/torch/nn/modules/module.html#Module

and search for __call__ one can eventually trace it back - at least in some cases - to a call to self.forward

import torch.nn as nn
import torch.nn.functional as F

class MyNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer1 = nn.Linear(784, 200)



    def forward(self, x):
        return F.ReLU(self.layer1(x))

x=torch.rand(10,784)
model=MyNN()
print(model(x))
print(model.forward(x))

will print the same values in the last two lines as the Module class has implemented __call___ so that's what I believe Python turns to when it sees model(x), and the __call__ which in turn eventually calls model.forward(x))

usr0192
  • 313
  • 3
  • 9
1

Specify a __metaclass__ and override the __call__ method, and have the specified meta classes' __new__ method return an instance of the class, viola you have a "function" with methods.

1

We can use __call__ method to use other class methods as static methods.

    class _Callable:
        def __init__(self, anycallable):
            self.__call__ = anycallable

    class Model:

        def get_instance(conn, table_name):

            """ do something"""

        get_instance = _Callable(get_instance)

    provs_fac = Model.get_instance(connection, "users")             
1

One common example is the __call__ in functools.partial, here is a simplified version (with Python >= 3.5):

class partial:
    """New function with partial application of the given arguments and keywords."""

    def __new__(cls, func, *args, **kwargs):
        if not callable(func):
            raise TypeError("the first argument must be callable")
        self = super().__new__(cls)

        self.func = func
        self.args = args
        self.kwargs = kwargs
        return self

    def __call__(self, *args, **kwargs):
        return self.func(*self.args, *args, **self.kwargs, **kwargs)

Usage:

def add(x, y):
    return x + y

inc = partial(add, y=1)
print(inc(41))  # 42
endless
  • 114
  • 1
  • 2
  • 5
1

This is too late but I'm giving an example. Imagine you have a Vector class and a Point class. Both take x, y as positional args. Let's imagine you want to create a function that moves the point to be put on the vector.

4 Solutions

  • put_point_on_vec(point, vec)

  • Make it a method on the vector class. e.g my_vec.put_point(point)

  • Make it a method on the Point class. my_point.put_on_vec(vec)
  • Vector implements __call__, So you can use it like my_vec_instance(point)

This is actually part of some examples I'm working on for a guide for dunder methods explained with Maths that I'm gonna release sooner or later.

I left the logic of moving the point itself because this is not what this question is about

Ahmed I. Elsayed
  • 2,013
  • 2
  • 17
  • 30
0

The function call operator.

class Foo:
    def __call__(self, a, b, c):
        # do something

x = Foo()
x(1, 2, 3)

The __call__ method can be used to redefined/re-initialize the same object. It also facilitates the use of instances/objects of a class as functions by passing arguments to the objects.

0
import random


class Bingo:

def __init__(self,items):
    self._items=list(items)
    random.shuffle(self._items,random=None)


def pick(self):
    try:
        return self._items.pop()
    except IndexError:
        raise LookupError('It is empty now!')

def __call__(self):
    return self.pick()

b= Bingo(range(3))
print(b.pick())
print(b())
print(callable(b))

Now the output can be..(As first two answer keeps shuffling between [0,3])

2

1

True


You can see that Class Bingo implements _call_ method, an easy way to create a function like objects that have an internal state that must be kept across invocations like remaining items in Bingo. Another good use case of _call_ is Decorators. Decorators must be callable and it is sometimes convenient to "remember" something between calls of decorators. (i.e., memoization- caching the results of expensive computation for later use.)

SSA
  • 117
  • 4