Are functions objects in Python?

Question:

I always hear this statement in Python (for topics such as decorators, etc. when you are passing functions, etc.) but have never really seen an elaboration on this.

For example is it possible to create a class c that has only one abstract method that is called with a set of opened and closed brackets.

i.e class c:
       @abstractmethod
       def method_to_be_called_by():
        ... 

so you can have

c(whatever parameters are required)

I could be way off the mark with my understanding here, I was just curious about what people meant by this.

Asked By: user3684792

||

Answers:

You are looking for the __call__ method. Function objects have that method:

>>> def foo(): pass
... 
>>> foo.__call__
<method-wrapper '__call__' of function object at 0x106aafd70>

Not that the Python interpreter loop actually makes use of that method when encountering a Python function object; optimisations in the implementation jump straight to the contained bytecode in most cases.

But you can use that on your own custom class:

class Callable(object):
    def __init__(self, name):
        self.name = name

    def __call__(self, greeting):
        return '{}, {}!'.format(greeting, self.name)

Demo:

>>> class Callable(object):
...     def __init__(self, name):
...         self.name = name
...     def __call__(self, greeting):
...         return '{}, {}!'.format(greeting, self.name)
... 
>>> Callable('World')('Hello')
'Hello, World!'

Python creates function objects for you when you use a def statement, or you use a lambda expression:

>>> def foo(): pass
... 
>>> foo
<function foo at 0x106aafd70>
>>> lambda: None
<function <lambda> at 0x106d90668>

You can compare this to creating a string or an integer or a list using literal syntax:

listobject = [1, 'two']

The above creates 3 objects without ever calling a type, Python did that all for you based on the syntax used. The same applies to functions.

Creating one yourself can be a little more complex; you need to have a code object and reference to a global namespace, at the very least:

>>> function_type = type(lambda: None)
>>> function_type
<type 'function'>
>>> function_type(foo.__code__, globals(), 'bar')
<function bar at 0x106d906e0>

Here I created a function object by reusing the function type, taking the code object from the foo function; the function type is not a built-in name but the type really does exist and can be obtained by calling type() on an existing function instance.

I also passed in the global namespace of my interpreter, and a name; the latter is an optional argument; the name is otherwise taken from the code object.

Answered By: Martijn Pieters

One simple way to see this is to create a function in the Python interpreter def bar(x): return x + 1 and then use dir(bar) to see the various magic attributes including __class__.

Yes, python functions are full objects.

For another approach, objects are functions if they have a magic __call__() method.

Answered By: shapr
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.