14

Having some issues with importing modules in python. This is my folder structure

my_app/
    app.py
    __init__.py (I want to import a function from this file)
    folder1/
        __init.py
        method1.py
    folder2/
        __init__.py
        method.py

In my root __init__.py I have this function

def want_to_be_run_elsewhere():
    pass

In my app.py, I want to import this function and run it when I start my application, but I'm unsure how to do it.

from my_app import want_to_be_run_elsewhere

This throws a no module named my_app

From what I can tell, I have all the necessary __init__.py files, so maybe it could be sys.path related?

I've read some similar threads on here but I haven't been able to solve this.

das-g
  • 9,718
  • 4
  • 38
  • 80
Cheese Puffs
  • 955
  • 3
  • 10
  • 19
  • Are `app.py` and `__init__.py` inside `my_app/` or not? – John Zwinck Oct 30 '16 at 09:51
  • Sorry for the sloppiness. Yes `app.py` and `__init__.py` is inside my_app/ and `app.py` is my entry point – Cheese Puffs Oct 30 '16 at 09:57
  • FWIW, it's not usual to define functions inside a `__init__.py` file. They are normally empty, or just have an `__all__` list in them. – PM 2Ring Oct 30 '16 at 10:11
  • Hmmm, OK. Maybe I should just consider moving the function then. I don't wanna import `__init__``but if that's the only way, I think i'll implement it another way. Thanks! – Cheese Puffs Oct 30 '16 at 10:18
  • Simplest way to figure this out which I always prefer is, try it importing in ipython with tab key. E.g. : import something. – Akshay Oct 30 '16 at 10:25
  • Are you running the script as `python my_app/app.py`? Then **don't do that!** Either write an external script, so you'd have `app.py` **outside** the `my_app` folder, or use the `-m` switch: `python -m my_app.app` – Bakuriu Oct 30 '16 at 10:34

1 Answers1

9

Usually you would do the import like

from . import want_to_be_run_elsewhere

This doesn't work here, because you are calling app.py. If you import my_app.app, it is part of the module. If you call it it is not. Importing from the module it is in using . will then not work.

You could either move app.py outside of my_app, removing it from the module and making imports work again.

Or you can use

from __init__ import want_to_be_run_elsewhere

in app.py

I believe

from my_app import want_to_be_run_elsewhere

will only work if you have actually pip install -e my_app/. Then it should work too.

Nils Werner
  • 34,832
  • 7
  • 76
  • 98
  • Alternatively, invoke `app.py` as a module in the package: From the dir **above** `my_app`, call `python -m my_app.app` or `python3 -m my_app.app`. See http://stackoverflow.com/a/11536794/674064 – das-g Oct 30 '16 at 10:23
  • Interesting! will have to try this – Nils Werner Oct 30 '16 at 10:24
  • 5
    I'd remove the suggestion to use `from __init__ import ...`. It's not the right way of doing things. It can even break code if some code in the submodules depends on the package name (e.g. if you use modules like `pickle` directly or `shleve` etc using that solution will make data unreadable). – Bakuriu Oct 30 '16 at 10:35