Organizing codes in libraries

Reading time5 min

In brief

Article summary

In this article, we discuss how codes should be organized in modules. In particular, we explain that we can organize them in files, and show how to import functions fromt hese files. This is essential for reusability of the codes you write.

Main takeaways

  • Codes can be stored in files (modules).

  • These modules can be imported in your scripts.

  • Modules should be designed as coherent collections of functions and variables.

  • Structuring codes like this is important for code reusability.

Article contents

1 — Importing functions

A key property of functions is that they can be easily reused. Functions may be thematically regrouped into separated files.

To call a function, called for instance funct_ext, defined in a separated file named my_functions.py, you need to explicitly indicate the Python interpreter where to find this function using the from ... import ... statement.

However, file my_functions.py should be found by the system. In other words, its directory should be in the PATH variable, which is a list of directories where Python will look for files. If it is not, you can either add your directory to the PATH at the system level, or add the directory to the Python variable sys.path.

Here are a few possible ways of importing a function in Python:

# Let's assume the file is not in the path
# For instance, assume it's in a directory "my_python_files" in the parent directory containing this script
import sys
import os
sys.path.append(os.path.join("..", "my_python_files"))

# Let's import func_ext
from my_functions import func_ext

# Now we can use the function
funct_ext()
# Let's assume the file is not in the path
# For instance, assume it's in a directory "my_python_files" in the parent directory containing this script
import sys
import os
sys.path.append(os.path.join("..", "my_python_files"))

# Let's import all functions from "my_functions.py"
from my_functions import *

# Now we can use the function
funct_ext()
# Let's assume the file is not in the path
# For instance, assume it's in a directory "my_python_files" in the parent directory containing this script
import sys
import os
sys.path.append(os.path.join("..", "my_python_files"))

# Let's import the "my_functions" module
import my_functions

# Now we can use the function precising the module in which it is
# This can be very practical when multiple modules have functions with the same name
my_functions.funct_ext()
/**
 * In Java, the entry point of a program is the 'main' function, in the 'Main' class, in a file named 'Main.java'.
 * To enable asserts, you should compile your program with `javac Main.java`.
 * Then, run it with the command `java -ea Main`.
 */
public class Main
{

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     * 
     * @param args Command line arguments received.
     */
    public static void main (String[] args)
    {
        // Now we can use the function
        MyFunctions f = new MyFunctions()
        f.func_ext();
    }

}

In Python, when you import a file, its whole contents is executed. For instance, let’s consider the following code, in a file named my_module.py:

def my_function () -> None:

    """
        A function that does something in your library.
        In:
            * None.
        Out:
            * None.
    """

    print("Hello")



# Let's test our code
print("Testing my function")
my_function()

Now, consider the following script:

# Import the function we want
from my_module import my_function

# Let's use the function
my_function()

When running this script, we get the following output:

Testing my function
Hello
Hello

In such situation, you probably didn’t want the testing part to be executed, but only want the function to be imported. To correct that, you can indicate to Python that a certain code has to be run only when the file is executed directly, i.e., not imported. Here is how to update my_module.py:

def my_function () -> None:

    """
        A function that does something in your library.
        In:
            * None.
        Out:
            * None.
    """

    print("Hello")



# This test indicates that we only run this when the file is executed directly
if __name__ == "__main__":

    # Let's test our code
    print("Testing my function")
    my_function()

Now, when running the script above again, we get the expected output:

Hello

Note that in Java, there is a single entry point called the main function, while each Python script can be run independently.

2 — Structuring code into separate files

Some code that you write may be generic enough to be used in other projects. In general, it is good to systematically separate your functions into thematic files. The codes you write now may be helpful in a few lessons, scholarship years, or maybe later.

To create a reuseable piece of code, we save the code into a separate file with a .py extension. Such a Python file is called a “module”.

To keep code organized, it’s good practice to split it into multiple files. For example:

  • main.py – The main script.
  • functions.py – Contains reusable functions.

The structure of a file such as functions.py should follow the following convention:

"""
    General description of the document contents.
"""

# Needed imports
# ...

# Various functions, well documented.
# ...

# Things to do when running this code directly
if __name__ == "__main__":
    # ...
// Needed imports
// ...



/**
 * General description of the class contents.
 * Here, we name the class Functions for the example.
 * It should match file name.
 */
public class Functions
{

    /**
     * Various functions, well documented.
     */
    // ...

}

Do not hesitate to have multiple such auxiliary files, corresponding to themes. For instance, you could have a file named math_functions.py, and another named network_functions.py.

Important

Beware of file names! If you name your files math.py or random.py for instance, Python will not be able to find the standard math or random modules when trying to import them.

To go further

Important

The content of this section is optional. It contains additional material for you to consolidate your understanding of the current topic.

To go beyond

Important

The content of this section is very optional. We suggest you directions to explore if you wish to go deeper in the current topic.

  • name.

    Short description.