0

I have this directory structure

  • folder
    • measuring_scripts
      • measure_something.py
    • analysis_scripts
      • plot_measured.py

I want to import a function from plot_measured.py into measure_something.py. So measure_something.py begins like this

PATH_TO_ANALYSIS_SCRIPTS = Path(__file__).resolve().parent.parent/'analysis_scripts'
print(PATH_TO_ANALYSIS_SCRIPTS)
import sys
sys.path.append(PATH_TO_ANALYSIS_SCRIPTS)
from plot_measured import something
# More stuff

This prints

/home/someone/blah/folder/analysis_scripts
Traceback (most recent call last):
  File "measure_something.py", line 5, in <module>
    from plot_measured import something
ModuleNotFoundError: No module named 'plot_measured'

How can I do this? I tried converting analysis_scripts into a module adding the __init__.py file and changing to from analysis_scripts.plot_measured import something but it is the same.

I know this has been asked a million times. I have myself even done this thousands of times in the past, but cannot see where I am failing this time...

user171780
  • 2,243
  • 1
  • 20
  • 43
  • Instead of from module import this have you tried importing whole module?. In my opinion it has something to do with path. – Lanre Aug 08 '22 at 07:55
  • You might want to check out how to [structure packages](https://docs.python.org/3/tutorial/modules.html#packages). With a package you can use [relative imports](https://docs.python.org/3/tutorial/modules.html#intra-package-references). – Jan Christoph Terasa Aug 08 '22 at 07:55
  • @JanChristophTerasa adding an `__init__.py` file in each folder and doing `from ...analysis_scripts.plot_measured import something` produces `ImportError: attempted relative import with no known parent package `. – user171780 Aug 08 '22 at 08:05
  • Because your whole `folder` should be one package. But then, you should move the scripts outside of the package. If you have code common to both scripts, move the code into its own package, and let both scripts import it. It does require some restructuring and rewriting, but it may benefit you in the long term. – 9769953 Aug 08 '22 at 08:06
  • No, the problem was nothing of what you are saying, it was just that `Path` object has to be casted to `str`. – user171780 Aug 08 '22 at 08:14

4 Answers4

0

This happened to me a few times. The obvious first thing to do is look for typos, some can be very easily missed.

I don't have an insight into why sometimes the sys.path.append method still does not work but you can try on of two other options:

replace sys.path.append(PATH_TO_ANALYSIS_SCRIPTS)

with sys.path.insert(0, PATH_TO_ANALYSIS_SCRIPTS)

or try:

sys.path.append('..') / sys.path.insert(0, PATH_TO_FOLDER)
from analysis_scripts.plot_measured import something
0
import sys

sys.path.append('../analysis_scripts')

import plot_measured

try this

0

Restructure your project, and refactor out the common code into a Python package (or module; but a package allows easire, more structure, future development of common code):

folder/
  my_package/
     __init__.py
     common_code.py
  scripts/
    analysis/
      plot_measured.py
    measuring/
      measure_something.py

Then, plot_measure.py would be something like

from my_package.common_code import function_a, function_b, constant_c
<other imports>

<code only relevant to this script>

and similar for measure_something.py.

Then, make sure your PYTHONPATH is correct (it needs to be set to full path name of folder), and you can run python scripts/analysis/plot_measure.py or python scripts/measure_something.py.

9769953
  • 10,344
  • 3
  • 26
  • 37
0

Found the solution

The problem was not the directory structure, was not any missing __init__.py, etc. It was solved by a very stupid cast from Path to str:

sys.path.append(str(PATH_TO_ANALYSIS_SCRIPTS))

Disappointed that it doesn't raise any kind of exception or warning if they want a string.

user171780
  • 2,243
  • 1
  • 20
  • 43