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.
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.
projIf 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]) )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With