This question already has answers here:
Using methods defined in __init__.py within the module
(2 answers)
Closed 8 years ago.
I have a file structure like this:
/mypkg
/__init__.py
/apkg
/__init__.py
How can I import /mypkg/__init__.py from /mypkg/apkg/__init__.py without using sys.path and within the package. I mean:
# I do not want to do this since path is already outside the package.
import sys
sys.path.append('../../')
import mypkg
Thanks again.
The short answer is that you can't. You can import from two locations:
Your modules located in directories in your Python path (sys.path).
Your current working directory.
To import from a parent directory, you need to add that directory to your path.
Furthermore, you're creating a circular dependency of sorts. I would strongly suggest your reconsider your overall structure because having a module import its "parent" doesn't really make sense. The fact that you need other files from a higher-level directory suggests that maybe the files in "apkg" should be at the same level as "mypkg".
In reply to your comment: you don't import __init__.py files. They act like a directory for your module so you can utilize the objects and definitions contained in the module. They can also perform initialization on the module contents when its imported, if necessary. There shouldn't be any code in an __init__.py file that you would want to import in another script.
Related
This question already has answers here:
Importing files from different folder
(38 answers)
How to fix "Attempted relative import in non-package" even with __init__.py
(22 answers)
Closed 2 months ago.
This is my project structure:
/my_project
/first_folder
first.py
/second_folder
second.py
second.py
def hello():
print('hello')
first.py
from ..second_folder import second
second.hello()
when i run first.py i get the following error:
ImportError: attempted relative import with no known parent package
How can I avoid this problem?
Normally when you run your script as the main module, you shouldn't use relative imports in it. That's because how Python resolves relative imports (using __package__ variable and so on...)
This is also documented here:
Note that relative imports are based on the name of the current
module. Since the name of the main module is always "__main__",
modules intended for use as the main module of a Python application
must always use absolute imports.
There are ways to make this work for example by hacking __package__, using -m flag, add some path to sys.path(where Python looks for modules) but the simplest and general solution is to always use absolute imports in your main script.
When you run a script, Python automatically adds the directory of your script to the sys.path, which means anything inside that directory (here first_folder is recognizable by interpreter. But your second_folder is not in that directory, you need to add the path to the my_project(which has the second_folder directory) for that.
Change your first.py to:
import sys
sys.path.insert(0, "PATH TO /my_project")
from second_folder import second
second.hello()
This way you can easily go into first_folder directory and run your script like: python first.py.
Final words: With absolute imports, you don't have much complexity. Only think about "where you are" and "which paths are exists in the sys.path".
There are several sources for this error but, probably, if your project directory is my_project then you don't need .. in the import statement.
from second_folder import second
This question already has answers here:
Attempted relative import with no known parent package [duplicate]
(4 answers)
Closed 1 year ago.
I am having following structure for my project
Object_Detection/
setup.py
setup.cfg
requirement.txt
object_detection/
models
__init__.py #contains from . import models
tests/
# inside tests dir
test_utils_image.py
__init__.py #empty
utils/
# inside utils dir
__init__.py #inside
utils_image_preprocess.py
utils_image.py
utils_tfrecord.py
Now init.py inside utils directory contains the following code.
# inside __init__.py
from . import utils_image_preprocess
from . import utils_image
from . import utils_tfrecord
Running above init.py files gives me an error:
ImportError: attempted relative import with no known parent package
test_utils.py inside tests dir contains the following code
# inside test_utils.py
from object_detection.utils import utils_image
While running test_utils.py I got the following error
ImportError: cannot import name 'utils_image' from 'object_detection.utils'
I have gone through this and this and tried to follow every aspect mentioned there but details about what to put inside init.py is not clear.
This problem seems to be associated with the structuring of init.py in different dir.
I have gone through various and got to know that if we keep even an empty init.py file then things will work out but I am not sure about my understanding.
Please let me know
what I am missing here and whether I am following the correct structure for packaging my code or not?
How to resolve these two errors?
Is this issue related to setting up source in IDE as I am using Vscode and I have also seen this has been mentioned at many places. See here? (But also tried the same code with PyCharm and encountered same error )
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):
Have you tried to do the following?
inside your utils __init__.py import your modules as follows:
from .utils_image_preprocess import <func1>... <rest of functions/classes you want to import>
from .utils_image import <func1>... <rest of functions/classes you want to import>
from .utils_tfrecord import <func1>... <rest of functions/classes you want to import>
And then in your test file do:
from object_detection.utils.utils_image import *
OR
from object_detection.utils.utils_image import <func1>,...
Also, make sure you don't have any circular dependencies in your modules. for example importing of function from your tests to your util module and vise versa
Python3 has two types of packages
Regular Packages
Namespace Packages
Regular packages contains init.py and namespace packages don't need to have init.py
Regarding your folder structure, it is correct, no change needed. You just need to import like this
from utils import utils_image
without mentioning the objects_detection as objects_detection is just a namespace package.
So it would be usefull when you would refer to the utils module from outside the objects_detection folder.
Here what python docs say about the namespace packages:
A namespace package is a composite of various portions, where each portion contributes a subpackage to the parent package.
I have a question. I have a directory setup like this:
folder/
main.py
/stuff/
__init__.py
function.py
/items/
__init__.py
class.py
My question is how would I import the class.py into the function.py? This setup is very specific and is unable to be changed. What would I need to put in order for this to work?
Your current directory structure seems ideal, so long as the application is started via main.py.
Python will always automatically add the parent directory of the main script to the start of sys.path (i.e. folder in your example). This means that the import machinery will give that directory priority when searching for modules and packages that are not part of the standard libarary.
Given this, you can import the classes.py module into function.py, like so:
from items import classes
(Note that I have renamed the module, because class is a python keyword).
If you later added another module to stuff, and wanted to import it into functions.py, you would do:
from stuff import another
and if a sub-package was added to items, and you wanted to import a module from that, you would do:
from items.subpackage import module
Imports specified in this top-down way can be used from any module within the application, because they are always relative to the parent directory of the main script, which has priority.
This question already has answers here:
Relative imports in Python 3
(31 answers)
Closed 4 months ago.
from ..box_utils import decode, nms
This line is giving error
ImportError: attempted relative import with no known parent package
What is this error and how to resolve this error?
Apparently, box_utils.py isn't part of a package. You still can import functions defined in this file, but only if the python script that tries to import these functions lives in the same directory as box_utils.py, see this answer.
Nota bene: In my case, I stumbled upon this error with an import statement with one period, like this:
from .foo import foo. This syntax, however, tells Python that foo.py is part of a package, which wasn't the case. The error disappeared when I removed the period.
If a different dictionary contains script.py, it can be accessed from the root. For instance:
If your program is structured...:
/alpha
/beta
/delta
/gamma
/epsilon
script.py
/zeta
...then a script in the epsilon directory can be called by:
from alpha.gamma.epsilon import script
in the latest python version, import it, directly don't use .. and .library
import the file which you want. this technique will work in the child directory.
If you import it from parent directory, then place the directory's full path.
package
|--__init__.py
|--foo.py
|--bar.py
Content of bar.py
from .foo import func
...
If someone is getting the exactly same error for from .foo import func.
It's because you've forgot to make it a package. So you just need to create __init__.py inside package directory.
This question already has answers here:
How to do relative imports in Python?
(18 answers)
Closed 6 years ago.
I have the following folder structure:
controller/
__init__.py
reactive/
__init__.py
control.py
pos/
__init__.py
devices/
__init__.py
cash/
__init__.py
server/
__init__.py
my_server.py
dispatcher/
__init__.py
dispatcherctrl.py
I need to import the module control.py in my_server.py, but it say ImportError: No module named controller.reactive.control despite the fact that I have added __init__.py in all the folders and sys.path.append('/home/other/folder/controller/reactive') in my_server.py.
The main file is in my_server.py.
I don't understand why, because dispatcherctrl.py do the same import and it work fine.
In Python3
You could use the importlib.machinery module to create a namespace and absolute paths for your imports:
import importlib.machinery
loader = importlib.machinery.SourceFileLoader('control', '/full/path/controller/reactive/control.py')
control = loader.load_module('control')
control.someFunction(parameters, here)
This method can be used to import stuff in whatever way you want in any folder structure (backwards, recursively - doesn't really matter, i use absolute paths here just to be sure).
Python2
Kudos to Sebastian for supplying a similar answer for Python2:
import imp
control = imp.load_source('module.name', '/path/to/controller/reactive/control.py')
control.someFunction(parameters, here)
Cross version way
You can also do:
import sys
sys.path.insert(0, '/full/path/controller')
from reactive import control # <-- Requires control to be defined in __init__.py
# it is not enough that there is a file called control.py!
Important! Inserting your path in the beginning of sys.path works fine, but if your path contains anything that collides with Python's built in functions, you will break those built in functions and it might cause all sorts of problems. There for, try to use the import mechanisms as much as possible and fall-back to the cross-version way of things.