Already having flat packages, I did not expect the problem that I encountered with nested packages. Here ...
Catalog layout
dir | +-- test.py | +-- package | +-- __init__.py | +-- subpackage | +-- __init__.py | +-- module.py
Contents of init .py
Both package/__init__.py and package/subpackage/__init__.py are empty.
module.py content
# file `package/subpackage/module.py` attribute1 = "value 1" attribute2 = "value 2" attribute3 = "value 3"
Contents of test.py (3 versions)
Version 1
# file test.py from package.subpackage.module import * print attribute1 # OK
This is a bad and unsafe way to import things (import everything in a large amount), but it works.
Version 2
# file test.py import package.subpackage.module from package.subpackage import module # Alternative from module import attribute1
A safer way to import, item by item, but it fails, Python doesn't want it: crash: the message "No module named module" is missing. However...
# file test.py import package.subpackage.module from package.subpackage import module # Alternative print module # Surprise here
... says <module 'package.subpackage.module' from '...'> . So the module, but not the module / -P 8-O ... uh
Version 3
# file test.py v3 from package.subpackage.module import attribute1 print attribute1 # OK
It works. So you are either forced to use the overkill prefix all the time, or use an unsafe method, like in version 1, and prevent Python from using the safe method? The best way that is safe and avoids an unnecessary long prefix is ββthe only one that rejects Python? Is it because he likes import * or because he likes too much prefixes (which doesn't help enforce this practice)?
Sorry for the hard words, but in two days Iβm trying to get around this stupid behavior. If I were completely wrong somewhere, it will leave me with the feeling that something is really broken in the Python package and subpackage model.
Notes
- I don't want to rely on
sys.path to avoid global side effects or *.pth , which are another way to play with sys.path with the same global effects. For a solution to be clean, it must be only local. Either Python is able to handle the subpacket or not, but it should not require playing with the global configuration in order to be able to process local files. - I also tried using the import in
package/subpackage/__init__.py , but he didnβt solve anything, he does the same and complains that subpackage not a known module, and print subpackage talks about this module (strange behavior, again).
I may be completely wrong (the option I would prefer), but it makes me feel very disappointed in Python.
Any other known method besides the three that I tried? Something I don't know about?
(Sigh)
-----% <----- edit ----->% -----
Conclusion so far (after user comments)
In Python, there is nothing like a real subpackage, since all package links refer only to the global dictionnary, which means that there is no local dictionary, which means that there is no way to manage the link of the local package.
You need to either use the full prefix, or a short prefix or an alias. How in:
Full prefix version
from package.subpackage.module import attribute1
Short prefix version (but duplicate prefix)
from package.subpackage import module
Or else, the option is higher.
from package.subpackage import module as m use_of (m.attribute1)
Factored Version
If you do not mind importing several objects at the same time in batch mode, you can:
from package.subpackage.module import attribute1, attribute2
Not in my first favorite taste (I prefer to have one import statement for the imported object), but there may be one that I personally approve of.
Update (2012-09-14):
Finally, in practice, this looks fine, with the exception of comments about the layout. Instead, I used:
from package.subpackage.module import ( attribute1, attribute2, attribute3, ...)