Chapter 10, Lesson 3 Text
Lesson Three: Managing Class Files
One of the main goals of Object-Oriented-Programming is to re-use code that has already been written - by you or by someone else. That's hard to do if your entire program is stored in a single source file! Any classes or functions that have already been written would need to be copied and pasted into your source file.
Instead of copying code into a single source file, it makes more sense to keep useful classes and functions in their own source files. You can then link to those secondary source files from your main program and simply use those handy features without cluttering up your own source code. You've already done this many times when you import Python libraries like random, datetime or math. In this lesson, you are going to learn how to store your classes and functions in separate source files and import those files into a main program.
Creating Separate Source Files
When should you write code in separate source files? If you think the function or class is likely to be re-used by another program later, using a separate source file could be a good idea. You may also choose to split code into multiple files if you are writing a long program and don't want to have a large amount of code in one giant file.
Normally, you want to place code that is closely related in a single file. For example, if you develop your own library of useful input validation functions, you might place those functions in a single file that can be easily imported when needed. If you have created a Python class, or a group of very similar classes, it would make sense to place that code in a separate file as well.
In our examples, we will typically place each class in its own source file. You are encouraged to do the same thing in your projects.
When creating source files, you need to select a name for each file. Remember that all Python source files end with a ".py" extension. Select a filename that generally describes what is in the file.
Be sure to follow standard Python naming conventions for your files (no spaces or special characters), even if your operating system lets you create a more unusual filename.
Importing External Source Files
In your main program, when you want to use code from an external file, you will use the import statement near the top. This should be familiar to you, as you have used the same import statement to include Python libraries like random, datetime and math. Simply write "import" followed by the name of your source file, without the ".py" extension.
In this example, we have created a separate source file called "Input.py". The file holds a class called "Validator" that defines a single function, get_integer().
class Validator: def get_integer(prompt, min, max): # loop until correct input received while True: try: inputString = input(prompt) # get user input inputInt = int(inputString) # try to convert to int if (inputInt >= min) and (inputInt <= max): # verify range return inputInt # success! except: continue # try again
Now, in order to use that Validator class from the main program, we need to add an import statement near the top of the main code. We'll start with "import Input" at the top. Then, we can use the Validator class defined inside the "Input.py" source file.
import Input data = Input.Validator.get_integer("What is the airspeed velocity of an unladen swallow? (10 - 50 mph): ",10,50) print("You guessed:",data)
To access a class or function inside an external source file, you begin by writing the name of the imported module(in this case, "Input". Then add a dot (.), followed by the class or function name (e.g. "Validator"). So, to call the get_integer() function on the Validator class in the Input module, you would write "Input.Validator.get_integer(...)" as demonstrated above.
Often, programmers will use the SAME name for both the source file and the class inside the file. We could have used "Validator.py" as the source filename in our example. You would then need to repeat that name when accessing the class inside the module - e.g. "Validator.Validator." You have seen this pattern before when using the datetime object from the datetime module ("datetime.datetime.").
Using Multiple Files with Our Online Python Engine
For convenience, when using our online Python engine to test code right in your web browser, we will always pre-define the names of all source files. You will see one source tab per file, with the filename inside the tab.
The left-most tab will always be considered the "main" program, so your program flow will always start in that file. All other source files will need to be imported in order to be used by the main code.
The example below shows our "Input.py" source file in a tab to the right of the main code in "main.py". Click on each tab to switch back and forth between the file contents. When you are ready, click "Run Code" to test the entire project. No matter which tab you are looking at when you click the button, the left-most source file ("main.py") will always run first.
Try It Now
Can you add another call to the get_integer() function on your own with a different prompt and range?
Storing Source Files on a File System
If you are working on your own computer, outside our online Python engine, then you will create and save each Python source file on your local hard drive. We recommend creating a separate directory for each project in order to keep your files neatly organized.
Your import statement must be able to find the target files on your local file system. So, if you have a statement like "import Widget", then you must save the "Widget.py" source file right next to your main code.
If you are not using an Integrated Development Environment such as Python's IDLE package, you can create source files on your own with a simple text editor like Notepad or TextEdit. Then, in order to run the project, open a command prompt or terminal window and change to the directory that contains your source files. Run the main source file by typing "python" and then the filename.
\My Projects\Sample>python main.py What is the airspeed velocity of an unladen swallow? (10 - 50 mph): 51 What is the airspeed velocity of an unladen swallow? (10 - 50 mph): 24 You guessed: 24 \My Projects\Sample>
However, if you install Python on your computer, it comes with an Integrated Development Environment that makes your life easier. You don't need to run separate text editors to create source files or use the command line to run the Python interpreter. All of those things can be done from within the IDE.
If you wish to complete Python projects on your own computer using a locally installed Python interpreter, Python source files and the Python IDLE development environment, please see our Supplemental Chapter on Local Python Installations for step-by-step instructions.
Python contains many advanced features for managing files in larger projects. It is possible to import source files that are in other directories and even define your own packages that include multiple files. We won't explore those concepts in this course, but you can read more about the import statement in the official Python documentation.
Work with Me: Best Friends
In this exercise, you are going to create a class named Bestie, stored in a separate source file named "Friends.py". This simulation of a best friend has a function called chat() that will respond to messages. You will then test your new class from the main program by calling the chat() function with different inputs.
To begin, click on the "Friends.py" tab and create your Bestie class in this source file.
- Begin the definition for the class named Bestie.
- Create and initialize a class variable named numMessages and set it equal to zero. This variable will track the number of times that chat() gets called.
- Define a class function called chat() inside Bestie. chat() should receive one parameter called input.
- Add the following logic to the chat() function:
- Increase the value in the Bestie numMessages variable by 1. Remember, to access a class-level variable, always start with the class name and a dot, like "Bestie.numMessages".
- If the numMessages variable is greater than 3
- Print the message "I'm too tired".
- return immediately so the rest of the function is skipped.
- Convert the input string to lower case. This will make comparisons easier. Remember you can use the str.lower() function and store the result back in the input variable.
- If "ride" is in the input, print the message "Sure I'll give you a ride".
- Else if "call" is in the input, print the message "I'll call you later".
- Else print the message "You are a mystery to me"
You can customize the keywords and response messages on your own!
Once your Bestie class is complete, click on the "main.py" tab to write your main program code.
- Add an import statement for the Friends.py source file.
- Call the chat() function on the Bestie class 4 times with the following inputs:
- "Hi there"
- "Can you give me a ride?"
- "Call and let me know"
- "Are you awake?"
When you are done, run your program to see how your best friend behaves! If you use the suggested keywords, response messages and test inputs, your program output will look like this:You are a mystery to me Sure I'll give you a ride I'll call you later I'm too tired
Try changing some of the keywords and response messages in the Bestie class. You can experiment with different input messages as well in the main code. Can you get your Bestie to respond the way you want?