There's more...

One aspect that makes Python particularly powerful is that it supports the programming techniques used in Object-Orientated Design (OOD). This is commonly used by modern programming languages to help translate the tasks we want our program to perform into meaningful constructs and structures in code. The principle of OOD lies in the fact that we think of most problems as consisting of several objects (a GUI window, a button, and so on) that interact with each other to produce a desired result.

In the previous section, we found that we could use classes to create unique objects that could be reused multiple times. We created an appButton class, which generated an object with all the features of the class, including its own personal version of app_cmd that will be used by the startApp() function. Another object of the appButton type will have its own unrelated [app_cmd] data that its startApp() function will use.

You can see that classes are useful to keep together a collection of related variables and functions in a single object, and the class will hold its own data in one place. Having multiple objects of the same type (class), each with their own functions and data inside them, results in better program structure. The traditional approach would be to keep all the information in one place and send each item back and forth for various functions to process; however, this may become cumbersome in large systems.

The following diagram shows the organization of related functions and data:

Data and functions

So far, we have used Python modules to separate parts of our programs into different
files; this allows us to conceptually separate different parts of the program (an interface, encoder/decoder, or library of classes, such as Tkinter). Modules can provide code to control a particular bit of hardware, define an interface for the internet, or provide a library of common functionality; however, its most important function is to control the interface (the collection of functions, variables, and classes that are available when the item is imported). A well-implemented module should have a clear interface that is centered around how it is used, rather than how it is implemented. This allows you to create multiple modules that can be swapped and changed easily since they share the same interface. In our previous example, imagine how easy it would be to change the encryptdecrypt module for another one just by supporting encryptText(input_text,key). Complex functionality can be split into smaller, manageable blocks that can be reused in multiple applications.

Python makes use of classes and modules all the time. Each time you import a library, such as sys or Tkinter or convert a value using value.str() and iterate through a list using for...in, you can use them without worrying about the details. You don't have to use classes or modules in every bit of code you write, but they are useful tools to keep in your programmer's toolbox for times when they fit what you are doing.

We will understand how classes and modules allow us to produce well-structured code that is easier to test and maintain by using them in the examples of this book.