-2

We all know that functions are objects as well. But how do function objects compare with functions? What are the differences between function objects and functions?

By function object I mean g so defined:

class G(object):
    def __call__(self, a):
        pass
g = G()

By function I mean this:

def f(a):
    pass
7
  • 7
    What do you mean "plain functions"? Commented Jan 24, 2017 at 16:30
  • 3
    Please give example what a function object and function is in your opinion. Commented Jan 24, 2017 at 16:31
  • 1
    This is like asking what is the difference between a plain int and an int object in Python... there are no plain ints. Commented Jan 24, 2017 at 16:40
  • "Everything in python is an object"
    – Aaron
    Commented Jan 24, 2017 at 16:47
  • @MikeMüller I edited the question explaining what I meant with function objects and function. Thanks for asking for a clearer question.
    – jimifiki
    Commented Jan 25, 2017 at 8:30

2 Answers 2

2

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>

So whenever you are defining a function in python an object like this is created. There is no plain way of function definition.

2
  • 1
    After the OP clarified his question this seems irrelevant. Commented Jan 25, 2017 at 8:50
  • Does a 'function' object have attribute 'set'? What about attribute 'get'? You are not answering my question.
    – jimifiki
    Commented Jan 27, 2017 at 9:03
1

TL;DR any object that implements __call__ can be called eg: functions, custom classes, etc..

Slightly longer version: (walloftext)

The full answer to your question on what's the difference sits within the implementation of the python virtual machine, so we must take a look at python under the hood. First comes the concept of a code object. Python parses whatever you throw at it into it's own internal language that is the same across all platforms known as bytecode. A very visual represnetation of this is when you get a .pyc file after importing a custom library you wrote. These are the raw instructions for the python VM. Ignoring how these instructions are created from your source code, they are then executed by PyEval_EvalFrameEx in Python/ceval.c. The source code is a bit of a beast, but ultimately works like a simple processor with some of the complicated bits abstracted away. The bytecode is the assembly language for this processor. In particular one of the "opcodes" for this "processor" is (aptly named) CALL_FUNCTION. The callback goes through a number of calls eventually getting to PyObject_Call(). This function takes a pointer to a PyObject and extracts the tp_call attribute from it's type and directly calls it (technically it checks if it's there first):

...
call = func->ob_type->tp_call //func is an arg of PyObject_Call() and is a pointer to a PyObject
...
result = (*call)(func, arg, kw);

Any object that implements __call__ is given a tp_call attribute with a pointer to the actual function. I believe that is handled by the slotdefs[] difinition from Objects/typeobject.c:

FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
       "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.",
       PyWrapperFlag_KEYWORDS)

The __call__ method itself for functions is defined in the cpython implementation and it defines how the python VM should start executing the bytecode for that function and how data should be returned (if any). When you give an arbitrary class a __call__ method, the attribute is a function object that again refers back to the cpython implementation of __call__. Therefore when you call a "normal" function foo.__call__ is referenced. when you call a callable class, the self.__call__ is equivalent to foo and the actual cpython reference called is self.__call__.im_func.__call__.

disclaimer

This has been a journey into somewhat uncharted waters for me, and it's entirely possible I have misrepresented some of the finer points of the implementation. I mainly took from this blog post on how python callables work under the hood, and some digging of my own through the python source code

3
  • Thanks for your answer which is interesting. Actually I was wondering more on features of the high level language such as why a 'function' object doesn't have attributes 'set' and 'get'. But I found interesting the informations you provided in your answer too.
    – jimifiki
    Commented Jan 27, 2017 at 9:06
  • Functions do implement __get__, It's what returns the text "<function A at 0x00000000064F5208>"
    – Aaron
    Commented Jan 27, 2017 at 14:11
  • it is much more common to use getters and setters to apply to an individual property of a class not the class itself. also functions do not inherit from the base object class, with the intent that if you want custom behavior, you can just implement it with classes. technically you could create your own function class, but it would be very slow and rather complicated. by not inheriting from the base object class, python can run it's c code instead to manage the calling of a code objec
    – Aaron
    Commented Jan 27, 2017 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.