jmoggee
jmoggee

Reputation: 143

Import from parent directory failed with ImportError

I'm busy developing an application in python, my application is structured as follows

main.py
pr/
    core/
        __init__.py
        predictor.py
    gui/
        predictor/
            __init__.py
            predict_panel.py
        __init__.py
        pr_app.py
    __init__.py

I launch the application using main.py

inside pr_app.py I've got

class PrApp(wx.App):
    PREDICTOR = Predictor()

inside predict_panel.py I can successfully do

from pr.core.predictor import Predictor

but for some reason I cannot do

from pr.gui.pr_app import PrApp

I get presented with

ImportError: cannot import name PrApp

Is there some kind of gotcha when importing from parent directories in python, or am I missing something?

Upvotes: 2

Views: 1284

Answers (3)

Lennart Regebro
Lennart Regebro

Reputation: 172367

I tried this and made a tree like yours, but with the addition of an __init__.py in the pr directory. Without that __init__.py your from pr.core.predictor import Predictor should fail, so I think you have it, but forgot to write it in your question.

I was not able to get the failure you did, it worked fine for me. I can do both imports from predict_panel.py, as I expected to.

However, if I from pr_app.py import predict_panel, then the import from predict_panel.py of PrApp will fail. This is because I have a circular import. You try to import predict_panel from PrApp during the import of PrApp and you try to import PrApp during the import of predict_panel. That would create an infinite recursion of imports, so it is not allowed.

The best way to solve this is to reorganize your code so you don't have to do circular imports. If PrApp imports predict_panel, why would predict_panel need PrApp? That's a sign of a flawed design.

However, the quickest way to fix it is to move one of the imports from the top of the module into the function/method where it's called. That's bad practice, but it will fix your problem quickly.

Upvotes: 2

poke
poke

Reputation: 388303

I launch the application using main.py

By doing that you correctly make your pr/ folder a package, so cross-referencing imports within that package should work. So both pr.gui.pr_app import PrApp and from ..pr_app import PrApp should work.

I think the problem in your case is that you haven’t made pr a real package. Try adding a __init__.py there too and it should work.

Upvotes: 0

erikbstack
erikbstack

Reputation: 13254

The reason for not being able to import from your parent directory is that each script considers itself as top it's import tree. The only other things it looks at is the sys.path. So as far as I know your only chance to import from above is to add the parent directory to your path (absolute not relative).

Put this at the top of your file:

import sys
import os
import inspect

#enable imports from dir above
sys.path.append(os.path.abspath(
    os.path.dirname(inspect.getfile(inspect.currentframe()))+"/.."))

Upvotes: -1

Related Questions