5

Background: I am trying to understand why static and class methods are not callable while being descriptors, while ordinary methods of a class (i.e. methods of a class which are neither static or class methods) and functions which are not attributes of classes are both descriptors and callable.

In Python, what is the definition of a callable type?

  1. From https://docs.python.org/3/reference/datamodel.html

    Callable types These are the types to which the function call operation (see section Calls) can be applied:

    Is the operator for "the function call operatation" ()? So is a callable type defined as a type whose instances the function call operator () can be applied to?

  2. From https://docs.python.org/3/reference/expressions.html#calls

    The primary must evaluate to a callable object (user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances, and all objects having a __call__() method are callable).

    Does it mean that a callable type may or might not have a __call__() method? If a class has a __call__() method, then it must be a callable type? If a class doesn't have a __call__() method, then it might or might not be a callable type?

    Do "user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances" not have a __call__() method? Are they instances of callable types? What specific types do they have respectively?

Thanks.

Tim
  • 1
  • 141
  • 372
  • 590

2 Answers2

4

Is the operator for "the function call operatation" ()? So is a callable type defined as a type whose instances the function call operator () can be applied to?

Yes, exactly.

Does it mean that a callable type may or might not have a __call__() method? If a class has a __call__() method, then it must be a callable type? If a class doesn't have a __call__() method, then it might or might not be a callable type?

For a given object to be a callable, it must define __call__, functions do, for example:

def foo():
    pass
callable(foo) # True

staticmethod's or classmethods (to continue from the previous question), don't define __call__:

s = staticmethod(foo)
callable(s)  # False

(callable essentially does something like getattr(foo, '__call__', False))

Do "user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances" not have a call() method? Are they instances of callable types? What specific types do they have respectively?

  • User defined functions (function type, like foo) have __call__.

  • Built-in functions (e.g max) also have __call__, see callable(max).

  • Methods of built-in objects, yes: callable(str.isupper).

  • Class objects, yes (type defines a __call__ for them):

    >>> class Spam: pass
    >>> callable(Spam) # True
    
  • Methods of class instances:

    >>> class Spam2: 
    ...     def do_spam(self):
    ...         return "spam"
    ...
    >>> callable(Spam2().do_spam)  # True
    

They are all callable because they define a __call__ special method. That's the only way to make an object callable.

As for staticmethods and classmethods, though they usually wrap callables (which they then expose via the descriptor protocol), they themselves are not callable since they don't define a __call__ special method.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • Thanks. Are there other objects which wrap callables but are not callables, but may act like callables? – Tim Sep 17 '17 at 12:56
  • @Tim not that I know of. Descriptors are special because the language invokes them (their `__get__`) behind the scenes and returns the callable they wrap. – Dimitris Fasarakis Hilliard Sep 17 '17 at 13:09
1

Check the definition of Callable

from collections import Callable

the source codes is as follows:

class Callable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __call__(self, *args, **kwds):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Callable:
            if any("__call__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

the tricky part is the method of __subclasshook__, so any classes who can find a __call__ method could be treated as a subclass of Callable, instead of inheriting from it directly.

PS: not only __subclasshook__ can do this, the register() method can also register another class as a subclass of the base class.

Menglong Li
  • 2,177
  • 14
  • 19
  • Thanks. (1) How do you show the definition of `Callable` class in Python? (2) Do you mean a callable type is defined as a type which has an attribute (data attribute or method attribute) named `__callable__`? (3) Do "user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances" have a `__call__()` method? Are they callable? What specific types do they have respectively? – Tim Sep 17 '17 at 12:06
  • (1) I use PyCharm as IDE, and clicked into the definition of Callable (you must import first: from collections import Callable); (2)(3) you can define a very simple function named foo, and use dir(foo) to see the attributes, you can see \__call__ is one of them. – Menglong Li Sep 17 '17 at 12:09