Python: importing a sub‑package or sub‑module
You seem to be misunderstanding how import
searches for modules. When you use an import statement it always searches the actual module path (and/or sys.modules
); it doesn't make use of module objects in the local namespace that exist because of previous imports. When you do:
import package.subpackage.module
from package.subpackage import module
from module import attribute1
The second line looks for a package called package.subpackage
and imports module
from that package. This line has no effect on the third line. The third line just looks for a module called module
and doesn't find one. It doesn't "re-use" the object called module
that you got from the line above.
In other words from someModule import ...
doesn't mean "from the module called someModule that I imported earlier..." it means "from the module named someModule that you find on sys.path...". There is no way to "incrementally" build up a module's path by importing the packages that lead to it. You always have to refer to the entire module name when importing.
It's not clear what you're trying to achieve. If you only want to import the particular object attribute1, just do from package.subpackage.module import attribute1
and be done with it. You need never worry about the long package.subpackage.module
once you've imported the name you want from it.
If you do want to have access to the module to access other names later, then you can do from package.subpackage import module
and, as you've seen you can then do module.attribute1
and so on as much as you like.
If you want both --- that is, if you want attribute1
directly accessible and you want module
accessible, just do both of the above:
from package.subpackage import module
from package.subpackage.module import attribute1
attribute1 # works
module.someOtherAttribute # also works
If you don't like typing package.subpackage
even twice, you can just manually create a local reference to attribute1:
from package.subpackage import module
attribute1 = module.attribute1
attribute1 # works
module.someOtherAttribute #also works
Python import module from within module in another subpackage
This is because python
doesn't know where to find main_package
in script_a.py
.
There are a couple of ways to expose main_package
to python
:
run
script_a.py
frommain_package
's parent directory (saypackages
). Python will look for it in the current directory (packages
), which containsmain_package
:python main_package/folder_1/folder_2/script_a.py
add
main_package
's parent directory (packages
) to yourPYTHONPATH
:export PYTHONPATH="$PYTHONPATH:/path/to/packages"; python script_a.py
add
main_package
's parent directory (packages
) tosys.path
inscript_a.py
In your
script_a.py
, add the following at the top:import sys
sys.path.append('/path/to/packages')
cannot import submodule from a module
If you want to be able to say ...
from object_detection.utils import utils_image
... then clearly the utils directory must be a subdirectory of the object_detection directory and not a sibling directory, i.e. at the same level.
Now for your other error:
ImportError: attempted relative import with no known parent package
You did not really specify under what circumstances you get this error other than saying "Running above init.py files gives me an error:". But how are you "running" these py files or what does that even mean?
If you are executing a script when this occurs (how else would you be getting this error?), the script must be invoked as a module (because scripts cannot have relative imports -- see below) as follows (we will assume that the script you are trying to execute is test_utils_image.py):
First, the parent directory of object_detection, which is Object_Detection, must be in the system path of directories to be searched for finding modules and packages referenced in import
statements. In general, this can be accomplished several ways, for instance
- The script you are executing is in Object_Detection (the directory of the script is automatically added to the
sys.path
list of directories to be searched by the interpreter). - Dynamically appending Object_Detection to the
sys.path
list of directories at runtime by your script. - Appending Object_Detection to the PYTHONPATH environment variable.
Item 1 above would not be applicable for this specific case since the module we are executing by definition is not in the Object_Detection directory.
Note that if your classes will eventually be installed with pip
, then site-packages will be the parent directory of object_detection, which is already in sys.path
.
Then you can execute your script as:
python -m tests.test_utils_image
If you want to execute this .py file as a script, for example by right-mouse clicking on it is VS Code, then see Relative imports for the billionth time, in particular the section Scripts can't import relative, which says it all -- it cannot work!
To invoke this as a script, just convert the relative imports to absolute imports. In fact, the PEP 8 Style Guide says:
Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on
sys.path
):
Python subpackage import no module named x
Your directory structure should be
package (choose whatever name you want for the high-level package name)
__init__.py
a.py
subpackage
__init__.py
b.py
The parent directory of package
needs to be in the sys.path
list of directories to be searched for resolving imports. This can be accomplished by having that directory being the current working directory when you invoke whatever program you are running or adding the directory to the PYTHONPATH
environment variable or modifying sys.path
at runtime before doing your imports.
Then a.py
should be either:
from package.subpackage.b import classX
or
from .subpackage.b import classX
Related Topics
Datetime Dtypes in Pandas Read_Csv
Ignore Python Multiple Return Value
How to Find All the Subsets of a Set, with Exactly N Elements
Selecting a Row of Pandas Series/Dataframe by Integer Index
Given a Url to a Text File, What Is the Simplest Way to Read the Contents of the Text File
Understanding Matplotlib.Subplots Python
Is There a Short Contains Function for Lists
Testing Code That Requires a Flask App or Request Context
Remove and Replace Printed Items
How to Pass a Default Argument Value of an Instance Member to a Method
Convert String Date to Timestamp in Python
Maximum Value for Long Integer
How to Execute Python Code from Within Visual Studio Code
Isprime Function for Python Language