Programmer's Python - Function Objects
Written by Mike James   
Monday, 07 January 2019
Article Index
Programmer's Python - Function Objects
Functions As Objects

Functions are Objects

So far we have been looking at Python functions viewed as any function in any language might be described, but as promised, Python functions are completely different.

They are objects.

This is something that you only find in languages that have been influenced by the early experimental object oriented languages such as Smalltalk. Python shares this idea with Ruby and JavaScript to name just two but it isn’t common in class-based languages such as Java, C#, C++ and so on. However, the advantages of implementing functions as objects is so great that languages that don’t use this approach have had to add features to make up for it. C# added delegates and later, along with other languages, lambda expressions. Python doesn’t need such additions but it does have a form of a lambda expression which it doesn’t really need – see later.

What does it mean that a function is an object?

When you write a Python function definition:

def sum(a,b):
    c=a+b
    return c

something more happens than in other languages.

When the Python system reads the function definition it does more than just store the name of the function in the dictionary. It creates a function object which stores the code of the function and sets a variable to reference it. The construction of an object to act as the function is key to the different way functions in Python work.

It is a good idea to think of a function definition more like:

sum = def(a,b):
        c=a+b
        return c

this is invalid syntax but if you think about it in this way you can see that the variable sum with a reference to the new function object is created.

The function object is a perfectly standard object but it comes with a code object as one of its attributes which stores the code. It is also an example of a callable which means you can use the invocation operator () to execute the code they contain.

Function objects have all of the built-in attributes that objects have and a few that are special and related to their callability.

Notice that:

sum

is a variable that references the function object and:

sum()

is an evocation of that function object and it evaluates to whatever that function returns.

It may be only the difference of a pair of parentheses but the difference is huge.

If you are familiar with a more traditional approach to functions then it can take time to reach a point where you think about things correctly and stop making silly mistakes.

You can add new attributes to a function object and make use of them:

sum.myAttribute=1
print(sum.myAttribute)

Notice that any attributes you create exist even when the function is not being evaluated, but local variables only exist while the function is being evaluated.

Function attributes and local variables have a different lifetime.

Why Are Functions Objects?

You may at this point be wondering why we bother to make functions objects?

After all it has already been stated that it is possible to write good Python code without giving the fact that functions are objects a moment’s thought.

What makes this approach so useful is often expressed by saying that in Python functions are first class objects.

What this means is that anything you can do with an object you can do with a function. In particular you can pass a function as a parameter to another function and you can return a function from another function.

These two simple features make things very much easier and we don’t have to invent additional mechanisms like delegates or lambdas to make them available.

The standard example is to consider a sort function which can accept a comparison function to use to order the things it is going to sort. A simpler, but less likely, example is a math function that can apply a function that you pass in:

def math(f,a,b):
    return f(a,b)
sum.myAttribute=1
print(math(sum,1,2))

Notice that the first parameter f is a function. More accurately it is a function object and the math function evaluates it and returns its result.

Of course this doesn’t have any practical advantage unless you are going to have a range of possible functions that can be passed as f but you can see how this might work in practice. Being able to customize one function by passing it others to use is a huge simplification and there are other advantages of function objects.

Summary

 

  • Functions in Python are objects and can be used anywhere an object can.

  • In particular you can pass a function as a parameter and return a function result.

  • Function parameters are passed by object reference which means changes to parameters do not affect the variables used as arguments. However, changes to mutable objects, i.e. attributes, do affect the objects in the calling program.

  • Functions can have attributes defined which have a lifetime beyond that of the function’s local variables.

  • Local variables exist only while the function is being executed, but attributes exist as long as the function object does.

  • Lambda expressions are lightweight ways of creating function objects. They simplify the syntax for passing functions as arguments.

  • Functions, like all Python objects, are essentially anonymous – they have variables which reference them rather than immutable names.

  • Functions can refer to their own attributes in code but exactly how to do this in a way that is immune from changes to the variables used to reference the function is more difficult that it first appears and needs closure for a reasonable solution

Programmer's Python
Everything is an Object

Is now available as a print book: Amazon

pythoncover


Contents

  1. Hello Python World
  2. Variables, Objects and Attributes
  3. The Function Object
    Extract - Function Objects
  4. Scope, Lifetime and Closure
    Extract - Local and Global  ***NEW
  5. Advanced Functions
    Extract -  Decorators 
  6. Class Methods and Constructors
  7. Inside Class
  8. Metaclass
  9. Advanced Attributes
    Extract - Properties
  10. Custom Attribute Access
  11. Single Inheritance
  12. Multiple Inheritance
  13. Class and Type
  14. Type Annotation
  15. More Magic - Operator Overloading

 

Advanced Attributes

 

 

Related Articles

Creating The Python UI With Tkinter

Creating The Python UI With Tkinter - The Canvas Widget

The Python Dictionary

Arrays in Python

Advanced Python Arrays - Introducing NumPy


appC

 



 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on, Twitter, Facebook or Linkedin.

Banner

<ASIN:1871962587>

 



Last Updated ( Monday, 07 January 2019 )