I'm trying to understand the import-logic in Python.
If you take this tutorial as a reference, I think you won't be able to, for example state:
from sound.effects import echo
At least, not from within the package.
However, Suds (a package I'm interested in) does something like that here
A fragment of suds/suds/builder.py:
from logging import getLogger
from suds import *
from suds.sudsobject import Factory
..
folder structure:
suds/
...no_package_init_file_here...
suds/
__init__.py
builder.py
sudsobject.py
...
How, and why does this work?
I thought it was kind-of 'not-allowed' to use the container package name within the package. As a rule of thumb.
Now, there is one thing I can think of: suds will add itself to the PYTHONPATH and thereby becomes accessible to every level. Is that the reason?
And, do you guys think that Suds has a smart solution here? Or is a bit hacky?
Thanks in advance.
both solutions are supported. from within a package you can use:
from mypackage import mymodule
or
import mymodule
and if you just want to import a single class from a module
from mypackage import mymodule.myclass
or
import mymodule.myclass
sounds like pythonpath..
After studying this a bit, I found out it all depends on the PYTHONPATH or sys.path
. So, from sound.effects import echo
works from within the sound
package (first example) when sound
is found in sys.path
. And that only happens if sound
is located in a directory that exists in sys.path
.
relative to executed script
When the executed script (.py file or interpreter) is called from a directory where the sound package can be found, not errors are raised. This is because that directory is the first element in the sys.path
list. But, when the executed script is inside the package itself, it won't find sound
and therefore a ImportError: No module named sound
will be raised. Unless of course, sound
is included at another level of sys.path
(for example in /usr/lib/python2.6/dist-packages
).
about suds
Now, for suds
this import statement was correct. And that is because the suds
package exists in the PYTHONPATH ( sys.path
). In that way, the from suds.sudsobject import Factory
calls the version of suds in PYTHONPATH (dist-packages).
extra :
In my case, I wanted to modify suds
source code and therefore I placed a copy of the entire dir in my lib: my_package/lib/suds/
. The calling script (.py) could however not find suds
because it was 1 level too deep. And then import errors were raised because suds could not be loaded properly
When you don't want suds
in/from the dist-packages
you can add it to sys.path
manually:
import sys, os
suds_parent = os.path.join(os.path.dirname(__file__), 'lib')
if suds_parent not in sys.path:
sys.path.append(suds_parent)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.