I am creating a python module. To test it i put the file in the same directory and then wrote the code
import mymodule
mymodule.dofunction
python then said >>>no module named mymodule but they are in the same directory.
Adapting from previous answer here. Explicitly state that you want to use the current directory.
Also, consider that you need an "__init__.py" file in each directory you are importing from.
import os, sys
lib_path = os.path.abspath('.')
sys.path.append(lib_path)
import mymodule
More information on the import system here.
Related
I have a directory like this:
-RootFolder/
- lib/
- file.py
- source/
- book.py
I'm at the book.py, how do I import a class from the file.py?
When you are running book.py, only it's directory is gonna be added to the sys.path automatically. You need to make sure that the path to the RootFolder directory is in sys.path(this is where Python searches for module and packages) then you can use absolute import :
# in book.py
import sys
sys.path.insert(0, r'PATH TO \RootFolder')
from lib.file import ClassA
print(ClassA)
Since you added that directory, Python can find the lib package(namespace package, since it doesn't have __init__.py)
If you start your program from RootFolder (e.g. python -m source.book), the solution by Irfan wani should be perfectly fine. However, if not, then some hacking is required, to let Python know lib also contains relevant code:
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).parent.parent / "lib"))
import file
from lib.file import some_module
I think this should work fine if the rootfolder is added to path.
If not, we need to do that first as shown by #Amadan and #SorousH Bakhtiary (just wanted to add some explanation);
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).parent.parent))
So here, Path(__file__) gives the path to the file where we are writing this code and .parent gives its parent directory path and so on.
Thus, str(Path(__file__).parent.parent) gives us path to the RootFolder and we are just adding that to the path.
I have a few seperate pythone file and I am using them to import another py file. Modules that trying to import them are in seperate folder I code sample is below
from tez.library.image_crop import ImageCrop
from tez.library.image_process import ImageProcess
from tez.library.image_features import ImageFeatures
from tez.const.application_const import ApplicationConst
from tez.library.file_operation import FileOperation
this code is in where I want to start the py file using commond line as "python samples1.py" and thrown an error as below
Traceback (most recent call last): File "samples1.py", line 1, in
from tez.library.image_crop import ImageCrop ModuleNotFoundError: No module named 'tez'
folder structure :
.tez
-- library
---- image_crop.py
---- image_process.py
---- image_features.py
--src
---- samples1.py
Python version : 3.8
Pip : 20.0.2
Windows 10 Pro 1909
If you are building a package called tez (and since you tried to import it I think you are). Then everything with tez needs to refer to itself locally. All the files in the tez package need to refer to each other with the "." and ".." imports.
In samples1.py:
from ..library.image_crop import <something>
EDIT:
It sounds like you are misunderstanding how python imports things. When you run "import X" in a python script, then python looks for a package named X under sys.path. You can append to sys.path at the top of your script if you have a custom package to look for.
import sys
sys.path.append(<directory of tez>)
import tez
However, it is strongly recommended that you should not be importing from a file that is under the directory structure of the package name. If "examples" is a directory of examples that use the package "tez" then "examples" should be located outside the package "tez". If "examples" is inside the package "tez", then "examples" should be doing local imports "with-in" the package.
Getting a handle on package use can be tricky.
sample.py can't see above of src folder, but you can tell Python to do this.:
import sys
import os
tez = os.path.dirname(os.path.dirname(__file__))
# __file__ is path of our file (samples.py)
# dirname of __file__ is "src" in our state
# dirname of "src" is "tez" in our state
sys.path.append(tez) # append tez to sys.path, python will look at here when you try import something
import library.image_crop # dont write "tez"
But this is not a very good design I think.
Recently started a new Python project.
I am resolving a import module error where I am trying to import modules from the same directory.
I was following the solutions here but my situation is slightly different and as a result my script cannot run.
My project directory is as follows:
dir-parent
->dir-child-1
->dir-child-2
->dir-child-3
->__init__.py (to let python now that I can import modules from here)
->module1
->module2
->module3
->module4
->main.py
In my main.py script I am importing these module in the same directory as follows:
from dir-parent.module1 import class1
When I run the script using this method it throws a import error saying that there is no module named dir-parent.module1 (which is wrong because it exists).
I then change the import statement to:
from module1 import class1
and this seemed to resolve the error, however, the code I am working on has been in use for over 2.5 years and it has always imported modules via this method, plus in the code it refers to the dir-parent directory.
I was just wondering if there is something I am missing or need to do to resolve this without changing these import statements and legacy code?
EDIT: I am using PyCharm and am running off PyCharm
If you want to keep the code unchanged, I think you will have to add dir-parent to PYTHONPATH. For exemple, add the following on top of your main.py :
import os, sys
parent_dir = os.path.abspath(os.path.dirname(__file__)) # get parent_dir path
sys.path.append(parent_dir)
Python's import and pathing are a pain. This is what I do for modules that have a main. I don't know if pythonic at all.
# Add the parent directory to the path
CURRENTDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
if CURRENTDIR not in sys.path:
sys.path.append(CURRENTDIR)
I have a python script that is trying to import another script somewhere in the file-system (path is only known at runtime).
To my understanding I need to use the imp module and this might work, but when loading the module I get an error that modules used by the imported module are not found.
Heres the code:
importer.py:
import imp
imp.load_compiled("my_module","full_path_to_my_module\\my_module.pyc")
my_module.py:
import sys
import another_module
When I run importer.py I get htis error message:
ImportError: No module named another_module
Whats going wrong here ?
I suspect that when 'importer.py' is loading 'my_module.pyc' hes also trying to load 'another_module' (thats good) but is looking in the wrong place (eg not 'full_path_to_my_module')
EDIT:
I tried adding 'full_path_to_my_module' to the system path:
import imp
import sys
sys.path.append(full_path_to_my_module)
imp.load_compiled("my_module",full_path_to_my_module+my_module)
But I still get the same error
Maybe I do something thats not necessary - Here's my goal:
I want to be able to use all functionality of 'my_module.pyc' inside 'importer.py'. But the location of 'my_module.pyc' is given as a parameter to 'importer.py'.
imp.load_compiled returns the compiled module object, it is different to the import statement which also binds the module to a name
import imp
my_module = imp.load_compiled("my_module", "full_path_to_my_module/my_module.pyc")
Then you can do something like:
my_module.yayfunctions('a')
Complete example session:
$ cat /tmp/my_module.py
def yayfunctions(a):
print a
$ python -m compileall /tmp/my_module.py
$ ls /tmp/my_module.py*
my_module.py my_module.pyc
$ python
>>> import imp
>>> my_module = imp.load_compiled("my_module", "/tmp/my_module.pyc")
>>> my_module.yayfunctions('a')
a
Edit regarding comment (ImportError: No module named another_module), I assume the error is caused by the code in my_module.pyc, and the another_module.py lives in the same directory
In that case, as others have suggested, it's simpler to just add the directory containing my_module to sys.path and use the regular import mechanism, specifically __import__
Here's a function which should do what you want:
import os
def load_path(filepath):
"""Given a path like /path/to/my_module.pyc (or .py) imports the
module and returns it
"""
path, fname = os.path.split(filepath)
modulename, _ = os.path.splitext(fname)
if path not in sys.path:
sys.path.insert(0, path)
return __import__(modulename)
if __name__ == '__main__':
# Example usage
my_module = load_path('/tmp/my_module.py')
my_module.yayfunctions('test')
It is since at the scope of import another_module your "full_path_to_my_module" isn't known.
Have you tried to add the path to known paths instead, i.e.:
import sys
sys.path.append("full_path_to_my_module")
You don't actually need to use the imp module to load pyc modules.
An easy way to try it out is to make two python modules, one importing from the other and run it. Delete then the imported .py file so you only get the .pyc file left: when running the script the import will work just fine.
But, for importing py files from random directories, you may want to add that directory to the python path first before importing it.
For instance:
import sys
sys.path.insert(0, "/home/user/myrandomdirectory")
Loading pyc files works the exact same way as loading a py file except it doesn't do a compile step. Thus just using import mymodule will work as long as the version number of the pyc is the same as the python you're running. Otherwise you'll get a magic number error.
If you module isn't in your path you'll need to add that to sys -- or if its a subdirectory, add a __init__.py file to that directory..
I have a module foo, containing util.py and bar.py.
I want to import it in IDLE or python session. How do I go about this?
I could find no documentation on how to import modules not in the current directory or the default python PATH.
After trying import "<full path>/foo/util.py",
and from "<full path>" import util
The closest I could get was
import imp
imp.load_source('foo.util','C:/.../dir/dir2/foo')
Which gave me Permission denied on windows 7.
One way is to simply amend your path:
import sys
sys.path.append('C:/full/path')
from foo import util,bar
Note that this requires foo to be a python package, i.e. contain a __init__.py file. If you don't want to modify sys.path, you can also modify the PYTHONPATH environment variable or install the module on your system. Beware that this means that other directories or .py files in that directory may be loaded inadvertently.
Therefore, you may want to use imp.load_source instead. It needs the filename, not a directory (to a file which the current user is allowed to read):
import imp
util = imp.load_source('util', 'C:/full/path/foo/util.py')
You could customize the module search path using the PYTHONPATH environment variable, or manually modify the sys.path directory list.
See Module Search Path documentation on python.org.
Give this a try
import sys
sys.path.append('c:/.../dir/dir2')
import foo
Following phihag's tip, I have this solution. Just give the path of a source file to load_src and it will load it. You must also provide a name, so you can import this module using this name. I prefer to do it this way because it's more explicit:
def load_src(name, fpath):
import os, imp
return imp.load_source(name, os.path.join(os.path.dirname(__file__), fpath))
load_src("util", "../util.py")
import util
print util.method()
Another (less explicit) way is this:
util = load_src("util", "../util.py") # "import util" is implied here
print util.method() # works, util was imported by the previous line
Edit: the method is rewritten to make it clearer.