Python: import the containing package - python

In a module residing inside a package, i have the need to use a function defined within the __init__.py of that package. how can i import the package within the module that resides within the package, so i can use that function?
Importing __init__ inside the module will not import the package, but instead a module named __init__, leading to two copies of things with different names...
Is there a pythonic way to do this?

Also, starting in Python 2.5, relative imports are possible. e.g.:
from . import foo
Quoting from http://docs.python.org/tutorial/modules.html#intra-package-references:
Starting with Python 2.5, in addition to the implicit relative imports described above, you can write explicit relative imports with the from module import name form of import statement. These explicit relative imports use leading dots to indicate the current and parent packages involved in the relative import. From the surrounding module for example, you might use:
from . import echo
from .. import formats
from ..filters import equalizer

This doesn't exactly answer your question, but I'm going to suggest that you move the function outside of the __init__.py file, and into another module inside that package. You can then easily import that function into your other module. If you want, you can have an import statement in the __init__.py file that will import that function (when the package is imported) as well.

If the package is named testmod and your init file is therefore testmod/__init__.py and your module within the package is submod.py then from within submod.py file, you should just be able to say import testmod and use whatever you want that's defined in testmod.

I'm not totally sure what the situation is, but this may solve your "different name" problem:
import __init__ as top
top.some_function()
Or maybe?:
from __init__ import some_function
some_function()

In Django, the file manage.py has from django.core.management import execute_manager, but execute_manager is not a module. It is a function within the __init__.py module of the management directory.

Related

How to import module inside package

Folder structure:
foo/
bar.py
__init__.py
test.py
foo/__init__.py has import bar
I am running test.py which has import foo
How do I get __init__.py to import bar.py?
ModuleNotFoundError: No module named 'foo'
Why does Python not create a new scope for my package and make the root for imports the foo directory?
Relative paths seem to not work either (I'm receiving a SyntaxError), although I'm looking for a solution that allows absolute paths.
import .bar
Two unacceptable answers:
I can't use import foo.bar. I need the foo package to have its own independent layer/scope so I can move it around anywhere in my computer and import it from anywhere. This means the root could change and import foo.bar will not always work.
I can't add the foo folder to my path. Obviously this would clutter the path and name conflicts could easily happen. Commence sense would say that this package's files should be separated from the path of what's using it.
Maybe there's a solution to add this package's directory to the path only for the scope of that package, somewhere in __init__.py?
Per PEP 328, the import X syntax is purely for absolute imports; since bar is not a top-level module here, the only valid import X syntax is import foo.bar.
The correct way to import bar from foo's __init__.py is:
from . import bar
Your point about wanting "absolute paths", but also wanting something like import .bar is impossible; even if import .bar worked, that's clearly a relative path (in that it only makes sense relative to the module that executes it; .bar would not make sense if imported outside of the foo package).
As for "Why does Python not create a new scope for my package and make the root for imports the foo directory?" the simple example is to imagine your sub-module is named math, not bar. What does:
import math
mean in this context? If it means your sub-module, how do you get the built-in, top-level math module? These problems (which I've encountered in Python 2 code when I failed to include from __future__ import absolute_import) are why PEP 328 and default absolute imports exist; one syntax is always absolute (removing ambiguity), and you can use the relative import syntax to perform relative imports (also without ambiguity) when needed.
Okay so you are having an error in __init__.py file in import bar right?
Well this shouldn't blow up but an easy alternate to this is from . import bar
EDIT
I understood the error occurs due to hierarchy and that __init__.py has a top level hierarchy. I found the following article of great help. Also see ShadowRanger's answer to this question.

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

Importing your own Python modules

I understand the four lines below:
import bpy
import numpy as np
from sys import argv
from os import *
But I've never seen the following lines:
from . uisun import *
from . hdr import sunposition
What about the dot? Does it refer to the position in the directory or something else?
The files uisun.py, sunposition.py, hdr.py are in the same directory within __init__.py which contains the code above.
By the way, this comes from a Blender addon.
ITs Intra-package References :
The submodules often need to refer to each other. For example, the surround module might use the echo module. In fact, such references are so common that the import statement first looks in the containing package before looking in the standard module search path. Thus, the surround module can simply use import echo or from echo import echofilter. If the imported module is not found in the current package (the package of which the current module is a submodule), the import statement looks for a top-level module with the given name.
When packages are structured into subpackages (as with the sound package in the example), you can use absolute imports to refer to submodules of siblings packages. For example, if the module sound.filters.vocoder needs to use the echo module in the sound.effects package, it can use from sound.effects import echo.
Starting with Python 2.5, in addition to the implicit relative imports described above, you can write explicit relative imports with the from module import name form of import statement. These explicit relative imports use leading dots to indicate the current and parent packages involved in the relative import. From the surround module for example, you might use:
from . import echo
from .. import formats
from ..filters import equalizer
This is just like playing around in a terminal. '.' means the current directory (where you are running your program from) and '..' means the parent directory. Read this for an example.

Python Subpackages not available for import

I'm working from the basis of this previously posted problem:
module importing itself
Essentially, that problem is solved, but in the "modulename.py" file, there is a class defined, with an init function, and a ui function. Inside the class, any line of the form:
import submodule
Will function just fine. However..
import submodule.subsubmodule
or
import subsubmodule
Will produce an ImportError.
All submodules and subsubmodules have an
__init__.py
file.
This often happens if you have multiple modules with the same name inside a package.
For example, consider:
mypkg/
__init__.py
toplevel.py
mypkg.py
If the toplevel.py file calls import mypkg.mypkg, it will actually be importing the mypkg.py file and not the package.
You can solve this by including from __future__ import absolute_import as the first line in toplevel.py, which will force it to import the top-level package.
Alternatively, you can use from . import mypkg in toplevel.py, which will explicitly import the mypkg.py file.

Python: Importing a file from a parent folder

...Now I know this question has been asked many times & I have looked at these other threads. Nothing so far has worked, from using sys.path.append('.') to just import foo.
I have a python file that wishes to import a file (that is in its parent directory). Can you help me figure out how my child file can successfully import its a file in its parent directory. I am using python 2.7.
The structure is like so (each directory also has the __init__.py file in it):
StockTracker/
└─ Comp/
├─ a.py
└─ SubComp/
└─ b.py
Inside b.py, I would like to import a.py: So I have tried each of the following but I still get an error inside b.py saying "There is no such module a".
import a
import .a
import Comp.a
import StockTracker.Comp.a
import os
import sys
sys.path.append('.')
import a
sys.path.remove('.')
from .. import a
Should do it. This will only work on recent versions of Python--from 2.6, I believe [Edit: since 2.5].
Each level (Comp and Subcomp) must also be have an __init__.py file for this to work. You've said that they do.
When packages are structured into
subpackages (as with the sound package
in the example), you can use absolute
imports to refer to submodules of
siblings packages. For example, if the
module sound.filters.vocoder needs to
use the echo module in the
sound.effects package, it can use from
sound.effects import echo.
Starting with Python 2.5, in addition
to the implicit relative imports
described above, you can write
explicit relative imports with the
from module import name form of import
statement. These explicit relative
imports use leading dots to indicate
the current and parent packages
involved in the relative import. From
the surround module for example, you
might use:
from . import echo
from .. import formats
from ..filters import equalizer
Quote from here http://docs.python.org/tutorial/modules.html#intra-package-references
If the Comp directory is in your PYTHONPATH environment variable, plain old
import a
will work.
If you're using Linux or OS X, and launching your program from the bash shell, you can accomplish that by
export PYTHONPATH=$PYTHONPATH:/path/to/Comp
For Windows, take a look at these links:
http://docs.python.org/using/windows.html
http://www.itechtalk.com/thread3595.html
EDIT:
To modify the path programmatically, you were on the right track in your original question. You just need to add the parent directory instead of the current directory.
sys.path.append("..")
import a

Categories

Resources