There are two ways you may want to run a Python script located in another folder – as a regular script or import and run it as a module. This article focuses on how we can do this.
Files and Directory Structure
We will use a file named runScript1.py to run two other files, script1.py and module1.py, located in another directory. We will execute script1.py as a regular Python script and module1.py as a module.
Here is the directory structure (it’s recommended you create these files in the tree structure shown and follow along),
We will keep editing runScript1.py, but the content of the other two files will remain the same throughout this post. It is as follows:
script1.py:
1 2 3 4 5 6 7 8 9 10 11 |
def add(a, b): return a+b def multiply(a, b): return a*b x1, x2 = 7, 5 print(f"{x1}+{x2} is equal to",add(x1, x2)) if __name__ == '__main__': x1, x2 = 3, 5 print(f"{x1}*{x2} is equal to",multiply(x1, x2)) |
This script has two functions to perform simple mathematical operations – add and multiply. We call multiply() function inside __name__ == ‘__main__’ and add() function outside.
Any code inside __name__ == ‘__main__’ is executed only when the script is executed as a regular Python file. If the script is imported as a module, the code under if-block will not be executed.
module1.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class BasicOperations(): def __init__(self, value1, value2): self.value1 = value1 self.value2 = value2 def add(self): return self.value1+self.value2 def multiply(self): return self.value1*self.value2 def power(self): return self.value1**self.value2 def integer_division(self): return self.value1//self.value2 if __name__ == '__main__': print("5 plus 7 is equals to: ", 5+7) s = BasicOperations(2, 5) print(s.multiply()) |
The module1.py has one class (BasicOperations()) with several functions performing different basic mathematical operations.
Executing Python Script on Terminal/Shell
In this article, we will consistently execute the runScript1.pyfile on the terminal by running the command “python3 script_name”.
You may run into the following error:
Just change “Python3” to “Python” in every command and script, so it looks like this: “python script_name”.
This assumes that you are on the directory containing the script. To change the directory to the folder containing the script, run “cd <directoty_containing_script>” on the terminal. In my case, I will execute runScript1.py as follows,
Note: In this post, we will use the dollar sign ($) to show that we are running the script on the terminal, for example, $ python3 runScript1.py.
Running Python Script in another Directory as Regular Script
Python script can be used to execute another script on a different directory with the help of either the os or subprocess module. Using these modules to run Python files is equivalent to running a Python script on the shell/terminal. The general syntax used is
1 2 |
os.system("python3 /path/to/script/to/execute") subprocess.run(["python3", "/path/to/script/to/execute"]) |
Note: If you have Python 2 and Python 3 installed on your computer and want to run Python 2 specify that.
Let’s now have the following code in our runScript1.pyand use it to execute script1.py
runScript1.py:
1 2 3 4 5 6 7 8 9 |
print("###os module###") import os os.system("python3 /home/kiprono/Desktop/test1/script1.py") print("###subprocess package###") import subprocess subprocess.run(["python3", "/home/kiprono/Desktop/test1/script1.py"]) |
After you run the script, you will get this message:
Output:
###os module### 7+5 is equal to 12 3*5 is equal to 15 ###subprocess package### 7+5 is equal to 12 3*5 is equal to 15
Notice that the code under __name__ == ‘__main__’ in script1.py is executed. This is because we run the script from runScript1.py as a regular script. To make the paths shorter, you can also use os.chdir() to change the current working directory (this is equivalent to using cd in the command line) and then pass the script names only as shown below
runScript1.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import os print("####os####") #change current working directory os.chdir("/home/kiprono/Desktop/test1/") # run script1.py using os module os.system("python script1.py") # run script1.py using subprocess module import subprocess print("####subprocess####") subprocess.run(["python", "script1.py"]) |
Run the code.
Output:
####os#### 7+5 is equal to 12 3*5 is equal to 15 ####subprocess#### 7+5 is equal to 12 3*5 is equal to 15
Running Python Script in another Directory as a Module
Whenever you import a module (which is just a Phyton file) in Python by writing “import module1“, for example, the interpreter will look for module1.py in the following places.
- The current working directory – the location of the script importing module1,
- List of folders set on the PYTHONPATH environment variable. We can add folders to this list whenever we want (this will make sense shortly).
- Folders configured at Python installation.
If you attempt to import a module that is not available in the above locations, Python will throw ModuleNotFoundError.
We can use the sys package to check and modify folders to look for. sys.path shows a list of directories the Python interpreter searches whenever a module is being imported.
runScript1.py:
1 2 3 |
import sys print(sys.path) |
Run the script.
Output:
['/home/kiprono/Desktop/test2', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/home/kiprono/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages']
Those are the directories Python will be looking for whenever you import modules. By default, the current directory is also searched.
In our case, it is the first element of the list (that is where runScript1.py is located). If we attempt to import module1.py, at this point, we will get ModuleNotFoundError because the folder containing it (‘/home/kiprono/Desktop/test1’) is not part of the sys.path.
Therefore, we must learn how to add a path to the Python environment.
Adding a path into the Python environment
There are two methods – using the sys module or editing Python environment variables explicitly (we will see how to do this in Linux, Mac, and Windows).
Method 1: Using the sys package
The function sys.path.append() allows us to add a path into the environment. Let’s use it to add ‘/home/kiprono/Desktop/test1’, then we can import the module1.py script as a valid Python module.
runScript1.py:
1 2 3 4 5 6 7 8 9 |
import sys sys.path.append("/home/kiprono/Desktop/test1") print(sys.path) import module1 s = module1.BasicOperations(1, 5) print(s.add()) |
Run the script.
Output:
['/home/kiprono/Desktop/test2', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/home/kiprono/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages', '/home/kiprono/Desktop/test1'] 6
As you can see, ‘/home/kiprono/Desktop/test1‘ has been added to the list of directories the interpreter will search, and therefore, we can import module1 and then load the BasicOperations() class. As said earlier, since module1.py is executed as a module, the code under __name__ == ‘__main__’ is not executed.
Every time we start another Python script and need to import modules, we have to append the directories to look for. To avoid having to do this, we can add the path(s) into the environment variable. We will see how to do that in Linux, macOS, and Windows.
Method 2a: Adding path to an environment variable (on Linux and Mac)
On Linux/Mac, you can check the current value of the variable by running this command on terminal
1 |
$ echo $PYTHONPATH |
That would be blank unless it has been modified before. To add the path containing our module, we need to:
Open .bash_profile (on Mac) or .profile (on Linux) (the file should be in the home folder(~)) and add the following line to the file:
1 |
export PYTHONPATH=$PYTHONPATH:/path/to/add |
Alternatively, you can run the following command on the terminal to append the line:
Linux:
1 |
echo "export PYTHONPATH=$PYTHONPATH:/path/to/add" >>~/.profile |
macOS:
1 |
echo "export PYTHONPATH=$PYTHONPATH:/path/to/add" >>~/.bash_profile |
If you are running your code on the terminal, you have to restart the terminal (or run source ~/.profile) for the changes to take effect, but if you are running the code on an editor, you might need to reboot the whole system.
runScript1.py:
1 2 3 4 5 6 7 8 |
import sys print(sys.path) import module1 s = module1.BasicOperations(1, 5) print(s.add()) |
Before adding a path into the environment, Python throws ModuleNotFoundError, but after adding the path, the code on runScript1.py was executed with no error.
You can add multiple paths using the line:
1 |
export PYTHONPATH=$PYTHONPATH:dir1:dir2:dir3 |
If you want to remove a path (say dir2), you can run the following command or remove the path on the .profile file:
1 |
export PYTHONPATH=$PYTHONPATH:dir1:dir3 |
Method 2b: Adding path to an environment variable (on Windows)
For Windows (using Windows 11), follow these steps:
- Open the Run dialog box by Clicking Windows Key + R,
- Type sysdm.cpl and click Enter. This should open the System Properties window. Go to the Advanced tab and click on Environment Variables at the bottom.
- To make the path recognizable by system-wise applications, we will add the path into System Variables.
- Click new or edit. A variable name can be anything but the variable value should be the path you wish to add. In my case: C:\Users\kipro\OneDrive\Desktop\run_file\test1
- Once done editing, click OK on the New System variable window and OK on the Environment variables window.
- Now, you may need to restart the Shell/terminal or the code editor you are using for changes to take effect.