trouble with custom imports Python3 - python

I am trying to import my own files in Python3. My directory looks like this:
/path/folder/__init__.py
/path/folder/custom_module2.py
/path/folder/custom_module.py
/path/launcher.py
init:
import custom_module
custom_module:
import custom_module2
def custom_function:
custom_module2.custom_function()
print('world')
custom_module2:
def custom_function2:
print('hello')
launcher:
import folder
custom_function()
it says that there is no module named custom_module

Actually, if you just put an empty file called __init__.py file, python will treat the directory as a package and you can import it with the dot notation.
__init__.py
custom_module2.py
custom_module.py
then from launcher.py
from folder.custom_module import custom_function
custom_function()
The init.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, init.py can just be an empty file, but it can also execute initialization code for the package or set the all variable, described later.
Source: https://docs.python.org/3/tutorial/modules.html#Packages

Related

Python help working with packages and modules

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

python import from sibling folder

I am trying to import a module from a python file that is in a sibling folder. I read several similar questions here and tried to apply solutions listed there, but I wasn't able to solve the problem.
The structure is as follows:
parentfolder/gfolder/codefolder/fileA.py
parentfolder/gfolder/utilfolder/util.py
gfolder, codefolder and utilfolder all have an __init__.py.
I'm trying to do in fileA.py:
import gfolder.utilfolder.util as util
I also tried adding before the import statement:
sys.path.append(".../parentfolder/")
And that didn't work either:
import gfolder.utilfolder.util as util
ModuleNotFoundError: No module named 'gfolder'
The solution in a similar question says to include __init.py__ in the directories, which I already have.
EDIT:
Now both sys.append and sys.insert work and the problem was that I included a slash at the end of the path. When I took it out, everything worked.
First of all, let me describe you the differences between a Python module & a Python package so that both of us are on the same page. โœŒ
A module is a single .py file (or files) that are imported under one import and used. โœ”
import aModuleName
# Here 'aModuleName' is just a regular .py file.
Whereas, a package is a collection of modules in directories that give a package hierarchy. A package contains a distinct __init__.py file. โœ”
from aPackageName import aModuleName
# Here 'aPackageName` is a folder with a `__init__.py` file
# and 'aModuleName', which is just a regular .py file.
Therefore, when we have a project directory named proj-dir of the following structure โคต
proj-dir
--|--__init__.py
--package1
--|--__init__.py
--|--module1.py
--package2
--|--__init__.py
--|--module2.py
๐Ÿ”Ž Notice that I've also added an empty __init__.py into the proj-dir itself which makes it a package too.
๐Ÿ‘ Now, if you want to import any python object from module2 of package2 into module1 of package1, then the import statement in the file module1.py would be
from proj-dir.package2.module2 import object2
# if you were to import the entire module2 then,
from proj-dir.package2 import module2
I hope this simple explanation clarifies your doubts on Python imports' mechanism. ๐Ÿ˜Š
As Andrew Cox answerd int the following thread Import a module from a relative path
You can add the subdirectory to your Python path so that it imports as a normal script
import sys
sys.path.insert(0, <path to gfolder>)
import gfolder
you can also add the directory to the PATH var of the Linux system (I use it while I'm working on a project, at the end i modified the PATH to it's origin value)
if you maintain the following structre than it is working out side the box
parentfolder/gfolder/codefolder/fileA.py
parentfolder/gfolder/utilfolder/util.py
parentfolder/gfolder/main.py
run main.py

Using a folder for personal modules in Python

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.

Import module into python not found

I am trying to import the module
import QSTK.qstkutil.qsdateutil as du
But I get the Error
ImportError: No module named QSTK.qstkutil.qsdateutil
My current working directory is
'c:\\Python27\\Lib\\site-packages\\QSTK'
and in the path C:\Python27\Lib\site-packages\QSTK\qstkutil there are the files
qsdateutil.py
qsdateutil.pyc
qsdateutil.pyo
Does importing QSTK work?
import QSTK
How about QSTK.qstkutil?
If not this is most likely a sys.path problem. Please post the result of:
>>>import sys
>>>sys.path
It should look like:
[ [...], 'C:\Python27\Lib\site-packages', [...] ]
Another thing you can check, is if 'C:\Python27\Lib\site-packages\QSTK\qstkutil' contains a file named '__init__.py'. From the module documentation:
The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.
try a fresh installation and make sure you run sudo python setup.py install , command after unpack-aging , QSTK. that process links QSTK.qstkutil.qsdateutil.

python modules hierarchy naming convention

I'd like to have modules/packages structure like following:
/__init__.py
/mymodule.py
/mymodule/
/mymodule/__init__.py
/mymodule/submodule.py
And then use modules like:
import mymodule
import mymodule.submodule
But it seems like file "mymodule.py" conflicts with "mymodule" directory.
What's the correct naming convention here?
If you want to make a package, you have to understand how Python translates filenames to module names.
The file mymodule.py will be available as the mymodule, assuming the interpreter finds it in a directory in the Python search path. If you're on a case-insensitive filesystem, it might also be importable with different capitalization (but you should avoid using such system-dependent behavior).
A package is a directory with an __init__.py file in it. There's been some movement recently to allow packages without those files, but I'm going to ignore that less-common case for this answer. A package becomes a module inside Python, with its code coming from the __init__.py file. So the file mypackage/__init__.py can be imported as mypackage.
There's no meaning to an __init__.py file directly in the Python search path (well, I suppose you could import it an an __init__ module, but this is probably a bad idea).
So, for your situation, here's the appropriate filesystem layout:
toplevel/
mymodule/
__init__.py # put code here for mymodule
submodule.py # put code here for mymodule.submodule
Only the toplevel folder should be in the Python search path.
You are dealing with a package. The package structure you should have is:
/some-parent-directory # This needs to be on sys.path
/mymodule # This is not really a module - it's a package
__init__.py # import mymodule
# init is loaded when you `import mymodule` or anything below it
some.py # import mymodule.some
implementation.py # import mymodule.implementation
files.py # import mymodule.files
/submodule
__init__.py # import mymodule.submodule
# init is loaded when you `import mymodule.submodule` or anything below it
submodule_impl.py # import mymodule.submodule.submodule_impl
goes.py # import mymodule.submodule.goes
here.py # import mymodule.submodule.here
As long as the parent directory is on sys.path you will be able to call import mymodule or from mymodule.submodule import something without issue.
If you want something to be available from the root level of a package (i. e. from mymodule import SomeItem or from a sub-package from mymodule.submodule import AnotherItem) then you can import it into the appropriate __init__.py file.
So, for example, let's say you wanted the class CustomClass defined in the submodule_impl.py module to be importable directly from submodule. Your submodule/__init__.py would have to contain the following:
from .submodule_impl import CustomClass
Then you would be able to import CustomClass directly from submodule (i. e. from mymodule.submodule import CustomClass)

Categories