First-class functions and classes
In Python, functions and classes are first-class objects. The phrase first-class object is a fancy way of saying that the data values can be accessed, modified, stored, and otherwise manipulated by the program they are a part of. In Python, a function is just as much a data value as a text string is. The same goes for classes.
When a function definition statement is executed, it stores the resulting function in a variable with the name that was specified in the def
statement, as shown in the following screenshot:

This variable isn't special; it's just like any other variable holding the value. This means that we can use it in expressions, assign the value to other values, or even store a different value in place of the original function.
The function value itself contains quite a few attribute variables, which we can access. More usefully, most of the time, we can add attributes to a function
object, allowing us to store custom information about a function as part of the function and access that information later, as shown in the following code example:

One common task that first-class functions make easy is assigning handlers to events. To bind the handler function to an event in Python, we just pass the function
object as a parameter when we call the binding function, as shown here:

That's a significant improvement over the hoops that C++ or Java imposes on us to do something similar. As function definition statements, class definition statements create a class object and store it in a variable. This can be confusing at first. Classes describe the type of object, how can they be objects themselves?
Think of it this way-a blueprint for a house describes the type of building, but the blueprint is still a thing in its own, right? It's the same with class objects. This means that like function objects, class objects can be stored in variables, and otherwise, be treated as data values. Most interestingly, they could be used as parameters to function calls.
The defaultdict class
As an example of why that's interesting, consider this-Python's standard library contains a data structure class called defaultdict
, which is like a dictionary except, when we try to look up a key that isn't already in the dictionary. It creates a new value and adds it to the dictionary, before returning it to the code that tried the lookup, as shown here:

How does the defaultdict
class know how to create the default value?
The defaultdict
class knows because we gave it class
as a parameter when we created the defaultdict
class. Thus, if we want a dictionary of list, we can give the defaultdict
class the list class, as its how to make a default parameter. As an aside, defaultdict
can also work with a function, as its how to make a default parameter.
The defaultdict
class actually doesn't care what that parameter is, as long as the object we passed can create a new object whenever the defaultdict
class needs a new default. This is an example of the duck typing we mentioned in the previous section. It doesn't matter whether the parameter is a function, a class, or anything else, so long as it behaves properly. If it doesn't behave properly, we'll be told what went wrong and where.
Attributes
We discussed a little while ago that we could add attributes to function objects, which is often handy. We could do something similar with classes, with one big difference- attributes that we add to functions are only visible to the code that has access to that function object, which usually doesn't include the code of the function itself, but attributes that we add to class objects are visible to any code that has access to the class object or to an object of the type described by the class.
This means that if we add an attribute to a class, the functions defined in that class will be able to access that attribute through the self
parameter, as shown in the following code example:

We need to be careful when adding attributes to classes because if we accidentally overwrite one of the class' attributes, we could break the class.
We have a greater ability to manipulate classes than functions. So, we need to use that ability more thoughtfully. Also, notice that, in this example, one of the attributes we added to the class is a function, which then proceeded to work exactly as if it had been defined as a part of the class from the beginning.
Next, let's take a short tour of some of the highlights of Python's standard library.