Say I have a folder named foo. Inside that folder is __init__.py, a folder called test, and another Python file called t1.py. Inside folder test is a Python file called bar.py, and in that file I am trying to do something like:
from foo import t1
And it gives me this error:
ModuleNotFoundError: No module named 'gmuwork'
Do I need to add something to environment variables or sys.path?
Absolute import
If you want to use
from foo import t1
Then yes, foo must be contained in sys.path.
From the docs:
When importing the package, Python searches through the directories on
sys.path looking for the package subdirectory.
In that case take a look at questions such as adding a file path to sys.path in python.
Relative import
Alternatively inside of bar.py you should be able to use
from ..foo import t1
as an intra-package reference.
Lastly: either way, you should put another empty __init__.py file inside of test to let Python know that folder is a subpackage.
Related
I need some help with working with a folder structure in python. I was given an structure like this:
/main-folder
/assets
somefiles.txt
/integrations
/module-folder
__init__.py
ingestion.py
__init__.py
models.py
Inside ingestion.py I have:
import os
from models import MyModel
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
some_function()
some_processing()
if __name__ == "__main__":
some_function()
Both __init__.py mentioned above are empty.
So I need to process some info and use the models module to store them. when trying to execute intestion.py directly from its dir it says: No module named 'models'. So I'm guessing I have to execute the whole thing as a package. I have no idea how should I import a module located above the package and can't touch the structure.
Any help woud be appreciated.
What you have to do is to add the module's directory to the PYTHONPATH environment variable. If you don't want to do this however, You can modify the sys.path list in your program where the Python interpreter searches for the modules to import, the python documentation says:
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
the directory containing the input script (or the current directory).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
the installation-dependent default.
After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended.
Knowing this, you can do the following in your program:
import sys
# Add the main-folder folder path to the sys.path list
sys.path.append('/path/to/main-folder/')
# Now you can import your module
from main-folder import models
# Or just
import main-folder
I'm having difficultly with important a python module from another folder. Here's how my folder looks currently
foldername/
__init__.py
A/
__init__.py
spam.py
grok.py
B/
__init__.py
foo.py
I'm trying to import the functions and classes from the grok.py file into the foo.py in B. This is how my foo.py looks like
from ..A.spam import func
However, I get the following error:
ValueError: attempted relative import beyond top-level package
Could somebody help me? I don't understand where I'm going wrong
You can't use '..' like you do on the command line. You have to add your 'A' folder to your Python path. You can use sys.path.append('/dir/of/A') and then from A.spam import func
Instead of using sys.path you could also add a *.pth-file to your python or anaconda "site-packages"-folder which contains the path to the folder "A".
Import via from A.spam import func as #bikemule already proposed.
I have created a folder named C:\Python27\Lib\site-packages\perso and inside I have put a file mymodule.py. The goal is to have this module accessible from any future Python script.
Let's do a D:\My Documents\test.py file:
import mymodule #fails
import perso.mymodule #fails
Why does it fail? How to import a module from C:\Python27\Lib\site-packages\perso? What are the best practice for using user-modules in all Python scripts of the same computer?
check PythonPath
create __init__.py to use perso as package
Python Modules:
In order to create a module you can do the following:
under <Python_DIR>\Lib\site-packages:
put you directory <module>. This directory contains your classes.
In <Python_DIR>\Lib\site-packages\<module> put an init file __init__.py,
This file define what's in the directory, and may apply some logic if needed.
for example:
__all__ = ["class_1", "class_2",].
Than, to import:
from <your_module> import <your_class>
For more information, read this.
I am creating module (with submodules). Lets call it lib. I am trying to make it work as following:
I am able to run it (there is lib.__main__). It uses lib.utils inside.
When executed part of its job is to load other file/module passed by user. Currently it does it by importlib.import_module( name ).
This loaded module also needs to use lib.utils.
I am having following choice:
In loaded module use import utils instead of import lib.utils. I find it somehow misleading and would like to aviod this.
Run module in any external way, even using file with only import lib.__main__ inside.
Only other thing I have tought of was doing sys.path.append(os.getcwd()). Not only it seems very dirty, but also makes log.utils module to load twice.
Is there anything that would allow me to execute lib.__main__, but require using import lib.utils in loaded module?
From the docs
If the script name refers to a directory or zipfile, the script name is added to the start of sys.path and the main.py file in that location is executed as the main module.
In your case, if you run python lib mymodule, lib is added to sys.path and __main__.py is executed. lib is not a package, its simply a directory in sys.path. __main__.py is not in a package and so package-relative imports don't work.
Since lib is in sys.path, its top level .py files can be imported directly and any subdirectories with __init__.py are importable packages. So, both __main__.py and mymodule could do import utils and get the same thing.
Now it gets confusing. Because you are sitting in lib's parent directory and because there is a lib.__init__.py, lib.utils is also valid. Its only that way because of your current directory (or maybe you added the directory to PYTHONPATH or something). So, you've got two different modules as far as python is concerned because you got there on two different paths.
The solution is to delete lib/__init__.py. lib shouldn't be package. Then you have the question of what to do with the modules like lib/utils.py. Normally, one would create a package directory and move the scripts there so that you get namespace encapsulation. Supposing you call that directory mypackages, then __main__.py and mymodule.py could both import mypackages.utils.
I'm hoping there's an easy answer to this question that I'm simply overlooking.
Here's the setup:
foo/
__init__.py
run.py
Contents of run.py:
import foo
Run the script:
$ python run.py
Traceback (most recent call last):
File "run.py", line 1, in <module>
import foo
ImportError: No module named foo
The only way I can figure out to address this is:
Contents of run.py:
import sys
import os
path = os.path.abspath(__file__)
sys.path.append(os.path.join(os.path.dirname(path), "../"))
import foo
So that works, but the problem (if I'm not mistaken) is that this adds the parent directory of foo/ to sys.path and thus searches all of the sibling folders of foo/ for Python modules.
There's a case I have where I really, really don't want to do that. I just want to add a single directory as a module to my path, but I can't figure out how to just add that module without adding that directory's parent directory and thus every other directory beneath that parent directory.
Am I overlooking something here? Is there an easy way I can add a script's parent folder as a module?
I don't quite see why run is meant to import its own parent package. After all, a package is just meant to be a way of collecting modules together; it's not meant to have significant functionality of its own.
Packages are a way of structuring
Python’s module namespace by using
“dotted module names”. For example,
the module name A.B designates a
submodule named B in a package named
A. Just like the use of modules saves
the authors of different modules from
having to worry about each other’s
global variable names, the use of
dotted module names saves the authors
of multi-module packages like NumPy or
the Python Imaging Library from having
to worry about each other’s module
names.
Are you sure you don't want run to import a sibling module? That you can do using relative imports.