Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python can't find module in parent directory

I have a folder structure for a Python project as follows:

proj/
├── cars
│   ├── honda.py
│   └── volvo.py
├── trucks
│   ├── chevy.py
│   └── ford.py
├── main.py
└── params.py

Contents of params.py:

""" Parameters used by other files. """

serial = '12-411-7843'

Contents of honda.py:

""" Information about Honda car. """

from params import serial

year = 1988
s = serial

print('year is', year)
print('serial is', s)

From within the proj/ folder I can run scripts using iPython:

$ cd path/to/proj/
$ ipython

In [1]: run cars/honda.py
year is 1988
serial is 12-411-7843

If I try to run the script using the python command, I get a module not found error for params.py:

$ cd path/to/proj/
$ python cars/honda.py
Traceback (most recent call last):
  File "cars/honda.py", line 5, in <module>
    from params import serial
ModuleNotFoundError: No module named 'params'

Why doesn't the approach using the python command work?

NOTE - The examples above are executed on a Mac using the Anaconda Python distribution. There is a similar question about an import issue when running on Windows vs Linux machines. However, my question is related to using iPython vs python on the Mac to run scripts.

like image 290
wigging Avatar asked Aug 15 '26 19:08

wigging


1 Answers

Above from params import serial insert:

import sys
[sys.path.append(i) for i in ['.', '..']]

This will add your current working directory and its parent directory to the list of locations from which you can import.

Handling imports when running script from a parent directory of proj

If you want to be able to import params into cars/honda.py when running your script from directories that are parents of project, you can use the following:

import sys
import os
from functools import reduce

# allow imports when running script from within project dir
[sys.path.append(i) for i in ['.', '..']]

# allow imports when running script from project dir parent dirs
l = []
script_path = os.path.split(sys.argv[0])
for i in range(len(script_path)):
  sys.path.append( reduce(os.path.join, script_path[:i+1]) )
like image 88
duhaime Avatar answered Aug 18 '26 11:08

duhaime



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!