how to import module from same level directory in python - python

as the question, i have my directory map like this
the formatOutput contain some function for better print
now, i want use a function in module printChecked.py in package formatOutput from findInfoSystem.py
i have tried create __init__.py in all folder to treat python it is a package (the advice i get from previous answer other post) but it always failed.
case 1: from formatOutput.printChecked import print_checked_box
error is: ModuleNotFoundError: No module named 'formatOutput'
case 2: from dttn.formatOutput.printChecked import print_checked_box
error is ModuleNotFoundError: No module named 'dttn'
case 3: from ..formatOutput.printChecked import print_checked_box
error is ImportError: attempted relative import with no known parent package
i don't want to use the sys.path method because i think it is not the good way to solve problem.
Help me please !

There are two classes of solutions to this problem:
modify the python import path
use the various setup tools or manually install .egg-links or symbolic links
to "install" your development modules in the python/lib/site-packages
The first approach is simple, but the second involves delving deeper
into a number of related topics. You'd probably want a virtual environment,
and a setup.py, etc.
So for the quick and dirty, two ways to modify the python import path:
set the PYTHONPATH= environment variable to include the parent directory of your packages
in findInfoSystem before importing formatOutput.printChecked, add this:
import sys
sys.path.append("..")

i found something very weird. I'm not import direct in module file but import to init.py file of package and then import to module file from packages name and it work. it like that:
from __init__.py of systemInfo package:
import sys,os
from formatOutput import prettyAnnounce,prettyParseData
current_directory = os.getcwd()
# sys.path.insert(1, current_directory+"/formatOutput/")
# sys.path.insert(1,current_directory+"/")
then in findInfoSystem.py module, im imported again like this:
from systemInfo import current_directory, prettyAnnounce as prCh , prettyParseData as prPD
yeah, now it's work like a charm. :))) i even not sure how

Related

ImportError: No module named UDPInterface

I am trying to build a Python app and ran into this import error:
ImportError: No module named UDPInterface
I am new to Python and hence I am unsure what dependency should I pip install. Tried searching on the internet but couldn't find anything useful. Any help would be highly appreciated.
from Functions import *
from ScriptComms import *
from ScriptForms import *
from IPInterface import TCP_APIInterface
from multiprocessing.synchronize import Lock
import UDPInterface
Given your imports it looks like it can't find the local python file UDPInterface.py. I believe it to be local given I cannot find any python module with that name. In the same directory level of your script there should be a file named UDPInterface.py. Could also be a simple typo in the filename or import. That or UDPInterface is in a sub/another directory and the import should be adjusted as so.
PS. You should avoid using * imports in Python (generally other languages also) as it can create namespace collisions (two modules with functions/classes/variables of the same name). Try from my_module import func1, func2 as it is more explicit and makes it easier to track down the source of the function/class/variable

ImportError: No module named even after I appended to system path

I have the following files:
./ElementExtractor.py
./test/ElementExtractorTest.py
In ElementExtractorTest.py, I am trying to import ElementExtractor.py like this:
import sys
sys.path.append('../')
import ElementExtractor
However, I am getting:
ImportError: No module named 'ElementExtractor'
How come it's not seen?
Is there a simple way to import another class with a relative reference?
The general answer to this question should be don't, I guess. Messing with relative paths means that the path is relative to the place from where you're calling it. That's why PYTHONPATH is worth embracing instead.
Let's assume, your directory structure looks like this:
./projects/myproject/ElementExtractor.py
./projects/myproject/test/ElementExtractorTest.py
Now, you're calling your script like this:
[./projects/myproject]$ python3.5 ./test/ElementExtractorTest.py
Your current directory is myproject and in ElementExtractorTest.py you're adding ../ directory to sys.path. This means, that ./projects/myproject/../ (i.e.: ./projects) is effectively added to your PYTHONPATH. That' why Python is unable to locate your module.
Your code would work from test directory though:
[./projects/myproject/test]$ python3.5 ./ElementExtractorTest.py
Now, by adding .. to sys.path you are effectively adding ./projects/myproject/test/../ (i.e. ./projects/myproject) to sys.path, so the module can be found and imported.
my folder structure
./test.py
./Data.py
from test.py
import Data
obj = Data.Myclass()
update
in your case
from ..ElementExtractor import MyClass
Hope this helps :)

Python - fails importing package

I have trouble importing package.
My file structure is like this:
filelib/
__init__.py
converters/
__init__.py
cmp2locus.py
modelmaker/
__init__.py
command_file.py
In module command_file.py I have a class named CommandFile which i want to call in the cmp2locus.py module.
I have tried the following in cmp2locus.py module:
import filelib.modelmaker.command_file
import modelmaker.command_file
from filelib.modelmaker.command_file import CommandFile
All these options return ImportError: No modules named ...
Appreciate any hint on solving this. I do not understand why this import does not work.
To perform these imports you have 3 options, I'll list them in the order I'd prefer. (For all of these options I will be assuming python 3)
Relative imports
Your file structure looks like a proper package file structure so this should work however anyone else trying this option should note that it requires you to be in a package; this won't work for some random script.
You'll also need to run the script doing the importing from outside the package, for example by importing it and running it from there rather than just running the cmp2locus.py script directly
Then you'll need to change your imports to be relative by using ..
So:
import filelib.modelmaker.command_file
becomes
from ..modelmaker import command_file
The .. refers to the parent folder (like the hidden file in file systems).
Also note you have to use the from import syntax because names starting with .. aren't valid identifiers in python. However you can of course import it as whatever you'd like using from import as.
See also the PEP
Absolute imports
If you place your package in site-packages (the directories returned by site.getsitepackages()) you will be able to use the format of imports that you were trying to use in the question. Note that this requires any users of your package to install it there too so this isn't ideal (although they probably would, relying on it is bad).
Modifying the python path
As Meera answered you can also directly modify the python path by using sys.
I dislike this option personally as it feels very 'hacky' but I've been told it can be useful as it gives you precise control of what you can import.
To import from another folder, you have to append that path of the folder to sys.path:
import sys
sys.path.append('path/filelib/modelmaker')
import command_file

No module named "data_utils"...But it is downloaded

So, I was having the simple error,
"No module named "data_utils"
when trying to import it into a python program. So I thought it must not have downloaded and spent like 20 mins trying to ensure a proper download. Turns out it was fine all along and the data_utils.py file is in the utils folder.
I'm really stuck because I see it right there, yet it simply won't import. I looked for a .bin after the __init__.py files but it seems like they are fine. Any help would be greatly appreciated. Thank you!
Deducing from your comment the answer would be:
The files have to be in the same directory /and some sub-directory for an import like import data_utils to work.
There are some way to get around this but to start try to keep it simple at first.
for example:
given a directory structure like this:
| --main.py
| --data_utils.py
| --train.py
and suppose you have a function remove_punctuation in data_utils:
you could use import that with:
from data_utils import remove_punctuation
or you could import all the functions (and or classes in data_utils) with:
from data_utils import *
or you can import data_utils with
import data_utils
# use remove_punctuation
data_utils.remove punctuation
The directory structure could also be:
|--main.py
|--bar
|--foo
|--src
|--train.py
and you could import remove_punctuation using
the same semantics as above qualifying the directory using dot notation:
from bar.foo import foo
EDIT: would module import like scipy have to be in the same directory?
Short answer
no
Long answer:
When you install scipy and numpy etc (packages you install from pip or using the sudo) they add themselves (their location) to the PYTHONPATH so you don't have to have them in the same directory as your project code.
Modules that you want to use globally must be added to your PYTHONPATH. Python searches for modules (roughly) in the directory and sub-directory of the file it is executing and in the PYTHONPATH.
if you want global import of your own modules
I.e, if you want to use data_utils.py everywhere you could do assuming you are using bash on linux and assuming you have data_utils.py in a directory named data-utils:
add an __init__.py to data-utils, so your directory structure would look like this:
|--data-utils
|--__init__.py
|--data_utils.py
then add this line to your ~/.bashrc:
export PYTYHONPATH=$PYTHONPATH:/path/to/data-utils
data-utils (and by extension data_utils.py) is permanently added to the PYTHONPATH and can be imported by any project code.

How to make `from . import utils` work

I have the following directory structure:
some-tools-dir/
base_utils.py
other_utils.py
some-tool.py
some-other-tool.py
some-other-tools-dir/
basetools -> symlink to ../some-tools-dir
yet-another-tool.py
In other_utils.py, I have:
import base_utils
Now, in yet-another-tool.py, I want to do:
import basetools.other_utils
That doesn't work, because Python does not recognize basetools as a Python package.
So I add an empty basetools/__init__.py.
Now, in other_utils, I get the exception:
import base_utils
ImportError: No module named base_utils
So I change that line to:
from . import base_utils
And yet-another-tool.py works now.
However, some-tool.py does not work anymore. It imports other_utils, and there I get the exception:
from . import base_utils
ValueError: Attempted relative import in non-package
Now, I can add this hack/workaround to some-tools-dir/*-tool.py:
import os, sys
__package__ = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
sys.path += [os.path.dirname(os.path.dirname(os.path.abspath(__file__)))]
__import__(__package__)
And in addition, make all local imports relative in those files.
That solves the problem, I guess. However, it looks somewhat very ugly and I have to modify sys.path. I tried several variations of this hack, however, I want to support multiple Python versions if possible, so using the module importlib becomes complicated, esp. because I have Python 3.2, and I don't like using module imp because it's deprecated. Also, it only seems to become more complicated.
Is there something I'm missing? This all looks ugly and too complicated for a use-case which doesn't seem to be too uncommon (for me). Is there a cleaner/simpler version of my hack?
A restriction I'm willing to make is to only support Python >=3.2, if that simplifies anything.
(Note that this answer was built by piecing together information from this answer and this question, so go up-vote them if you like it)
This looks a bit less hacky, and at least works with Python 2.7+:
if __name__ == "__main__" and __package__ is None:
import sys, os.path as path
sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
from some_tools_dir import other_utils
I think the main reason you're finding this difficult is because it's actually unusual to have executable scripts inside of a python package. Guido van Rossum actualy calls it an "antipattern". Normally your executable lives above the root directory of the package, and then can simply use:
from some_tools_dir import other_utils
Without any fuss.
Or, if you want to execute a script that lives in the package, you actually call it as part of the package (again, from the parent dir of the package):
python -m some_tools_dir.other_utils
Are you be able to add the top root path into PYTHONPATH ?
If so, you can then add
__init__.py
file into some-tools-dir (and/or some-other-tools-dir)
Then from other_utils.py you do
from some-tools-dir import base_utils
And in yet-another-tool.py you do
from some-tools-dir import other_utils
You can then remove the symlink, and have proper namespacing.

Categories

Resources