Book Image

Daniel Arbuckle's Mastering Python

By : Daniel Arbuckle
Book Image

Daniel Arbuckle's Mastering Python

By: Daniel Arbuckle

Overview of this book

Daniel Arbuckle's Mastering Python covers the basics of operating in a Python development environment, before moving on to more advanced topics. Daniel presents you with real-world solutions to Python 3.6 and advanced-level concepts, such as reactive programming, microservices, ctypes, and Cython tools. You don't need to be familiar with the Python language to use this book, as Daniel starts with a Python primer. Throughout, Daniel highlights the major aspects of managing your Python development environment, shows you how to handle parallel computation, and helps you to master asynchronous I/O with Python 3.6 to improve performance. Finally, Daniel will teach you the secrets of metaprogramming and unit testing in Python, helping you acquire the perfect skillset to be a Python expert. Daniel will get you up to speed on everything from basic programming practices to high-end tools and techniques, things that will help set you apart as a successful Python programmer.
Table of Contents (13 chapters)

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.