Reputation: 1127
I have searched this and found many answers, all of which tell me to do exactly what I am doing, here is my directory structure:
app/
+-- __init__.py
+-- app_manager.py
+-- app_gui/
| +-- __init__.py
| +-- app_gui.py
in app_gui.py I have:
import tkinter as tk
from tkinter import ttk
from app_manager import AppManager
in app manager:
class AppManager():
def __init__(self):
""" default constructor for app manager """
In Visual Code, it actually resolves this to an auto completion, which tells me that at least Visual Code sees it as correctly done. However, if I run this I get the following error:
ModuleNotFoundError: No Module named "app_manager"
Edit
Full stack trace when changing to from app.app_manager import AppManager
:
Traceback (most recent call last):
File ".\app_gui\app_gui.py", line 4, in <module>
from app_manager import AppManager
ModuleNotFoundError: No module named 'app_manager'
Upvotes: 1
Views: 5497
Reputation: 9321
Running python code like this is hacky at best.
Use a setup.py
This will require some small changes but will pay immediate benefits.
You will then be able to use your app
package like any other installed package.
.
├── app
│ ├── app_gui
│ │ ├── app_gui.py
│ │ └── __init__.py
│ ├── app_manager.py
│ └── __init__.py
└── setup.py
from setuptools import find_packages, setup
setup(name='app',
version='0.0.1-dev',
description='My app package',
install_requires=['tkinter'],
packages=find_packages(),
zip_safe=False)
from app.app_manager import AppManager
manager = AppManager()
From the same dir as setup.py
run:
$> python setup.py develop
This will symlink the package into your site-pacakges folder where you can treat it like any other package. i.e. import it using import app
from scripts located anywhere on your system.
Upvotes: 0
Reputation: 2529
Since app_manager.py
is a directory above app_gui.py
, I believe your import (if you wish to use a relative import) should be
from ..app_manager import AppManager
EDIT to address error in comments: If you try to run this file directly, you will get a ValueError
like in the comments. Relative imports work between modules inside of packages. Let's say that you use the import I wrote above, and then you have a file ONE LEVEL ABOVE your app
directory called stuff.py
, with the following contents:
import app.app_gui.app_gui
print('hello')
Running stuff.py
would look like:
$ python stuff.py
hello
In other words, executing a file with relative imports directly with the python interpreter will result in an error, as it was not intended to be used this way. Rather, your model should be imported and executed by something outside of the module itself.
If you have a __main__
file inside of your app
directory with the exact same code, you can also execute the module directly.
$ cat app/__main__.py
import app.app_gui.app_gui
print('hello')
$ python -m app
hello
Upvotes: 2