0

In my python script L47_trial.py, which has the following relative path with respect to my project:

my_scripts/04-trial/L47_trial.py

there is this import line

from ..starting_template import load_img

which should import the function load_img from the script starting_template, which has the following relative path with respect to my project:

my_scripts/starting_template.py

So, to be clear:

- my_scripts/
    - 04-trial/
        - L47_trial.py
    - starting_template.py

However, when I run

python my_scripts/04-trial/L47_trial.py

from my project directory (the folder one level upper with respect to my_scripts), I get this error:

from ..starting_template import load_img
ImportError: attempted relative import with no known parent package

My thinking is that as I run the file, python should do a relative import starting form the path of my_scripts/04-trial/L47_trial.py, so,
if starting_template were in the same directory of L47_trial.py (that is 04-trial/), I would do

from starting_template import load_img

but since starting_template is one level upper, then I would expect

from ..starting_template import load_img

to work.

What is the problem with my import?

Is it forbidden in python to import a script "from directories one level above the current script's one"?

What I tried

I tried to change

from ..starting_template import load_img

to

from my_scripts.starting_template import load_img

but I get

from my_scripts.resources.starting_template import load_img
ModuleNotFoundError: No module named 'my_scripts'

Why cannot it find my_scripts folder ?

2)

I tryed to move starting_template.py in the folder my_scripts/resources/ and change

from ..starting_template import load_img

into

from my_scripts.resources.starting_template import load_img  # refactoring made by VScode

but I get again

from my_scripts.resources.starting_template import load_img
ModuleNotFoundError: No module named 'my_scripts'

Notes

Note: I have tested that by moving starting_template.py into my_scripts/S04-trial and changing

from ..starting_template import load_img

to

from starting_template import load_img

solves the issue, but I would like to keep the file there where it is.

Note: The directories my_scripts and my_scripts/S04-trial contain a void file __init__.py

Tms91
  • 3,456
  • 6
  • 40
  • 74
  • You cannot use relative imports in scripts. – mkrieger1 Jul 30 '23 at 16:42
  • Does this answer your question? [Relative imports in Python 3](https://stackoverflow.com/questions/16981921/relative-imports-in-python-3) – mkrieger1 Jul 30 '23 at 16:44
  • @mkrieger1 "You cannot use relative imports in scripts" do you mean it is only supported by frameworks such as Django, Flask, etc? – Tms91 Jul 30 '23 at 16:46
  • 1
    I'm not sure what you mean by that. That has nothing to do with frameworks. You can use relative imports in files that are imported as a module and part of a package, but not in files that are executed as a top-level script (i.e. by executing `python3 path/to/script.py`). – mkrieger1 Jul 30 '23 at 16:47

1 Answers1

0

I think I understood my bias.

I have developed the current project by replicating the import statements I made in a Django project:

- app_m/
    - algorithms/
        - handling.py
    - __init__.py
    - entity_relationship_models.py

Inside handling.py:

from app_m.entity_relationship_models import my_function

This line of import successfully run, and the structure of the Django project is the same of the one in my question:

app_m/                        --> my_scripts 
algorithms/                   --> 04_trial7
handlers.py                   --> L47_trial.py
entity_relationship_models.py --> starting_template.py

However, relative imports on Django work differently.

Django handles the relative import, while calling the scripts from command line as top-level scripts, does not support it.

As stated by @mkrieger:

one can use relative imports in files that are imported as a module and part of a package, but not in files that are executed as a top-level script (i.e. by executing python3 path/to/script.py)

Some information about relative imports in Django

I could not find a clear statement on Django official documentation, but it seems that Django treats by default every app as a package, and that is the reason why in Django projects one can use relative imports, as it emerges from this illuminating answer on SO:

You can only use relative imports when you're importing from the same app.

Other useful resources I found:

Use absolute imports when necessary and prefer explicit relative imports for your local Django code.

from a post on learndjango.com

when you’re running Django, your “current directory” is not the directory for each file being run - it’s the directory where you’re running manage.py. Relative imports are relative to that location, not the location of the function currently being executed.

from a thread on djangoproject.com

Tms91
  • 3,456
  • 6
  • 40
  • 74