Reputation: 26717
I'm writing a little package and I'm trying to include a demo script within it as an example. However, I can't seem to import the package cleanly from within as though I was outside of it.
With a directory structure like:
trainer/
__init__.py
helper.py
trainer.py
[...more files...]
demo.py
In demo.py
I can't do from .. import trainer
as it complains "Attempted relative import in non-package", despite the __init__.py
. If I move the demo up a directory and import trainer
it works fine, but I was trying to keep it together with the package.
The hack-looking import __init__ as trainer
works, but eeeew.
Importing the various bits from all over the module directly also works, but makes for a messy example. Am I wholly misguided in my attempt or is there a better solution?
Upvotes: 1
Views: 227
Reputation: 70552
If you're trying to run demo.py
as python demo.py
, the problem that you're having is likely the same as here.
What's happening is that Python's relative import mechanism works by using the __name__
of the current module. When you execute a module directly, the __name__
gets set "__main__"
regardless what the actual module name is. Thus, relative (in-package) imports don't work.
To remedy this, you can do the following:
Execute demo.py
as a module within a package, like so: python -m trainer.demo
. This should fix the error, but you'll still be importing the trainer.py
module instead of the package.
Now add from __future__ import absolute_import
to demo.py
, which will cause your imports to be absolute-only by default, meaning that relative imports have to explicit (as in, from . import (...)
). This is force import trainer
to import the entire top-level package, instead of the module.
Upvotes: 2
Reputation: 40688
The way you organize the files, demo.py becomes part of the package, which might or might not be what you want. You can organize your files a little differently, moving demo.py outside of the trainer directory:
TopDir/
demo.py
trainer/
__init__.py
helper.py
trainer.py
[... more files ...]
Then, demo.py can do something like:
from trainer import trainer, helper
Upvotes: 0