if there is a directory /home/project/aaa
.
and I know that it is a Python package.
so, how can i import this module by just knowing its path.
means that, i hope that code is worked:
aaa = load_module("/home/project/aaa")
the only way i knew is that, adding /home/project
to sys.path
but it maybe incur some problem:
if i add /home/project
to sys.path
and if there a dir pytest
in path /home/project
.
then the official pytest package would not work.
i try importlib
yet.
but it seems that importlib
can just import a file as a module, not a path.
so, i try it:
aaa = importlib.import_module("aaa", "/home/project")
or
aaa = importlib.import_module("aaa", "/home/project/aaa")
both of them are not work.
so, is there any other way to do what i want?
oh, i am using Python3.6
UPDATED AT 20170628
(NOTICE: there is a __init__.py
in folder /home/project/aaa
)
all solutions i known is that import module from a single file.
if there is bbb.py
file in folder /home/project/aaa
then, add /home/project/aaa
to sys.path
or __path__
(whatever)
import bbb
is worked, but not the import aaa
what i wanna ask is how to import folder (or directory) as a module.
for my example, folder aaa
is consided as a module.
i wanna use import aaa
not import {SOMETHING IN AAA}
Here are five different ways of how to accomplish that task.
For the following considerations I refer to Python 3.5+.
Finder
Python uses finders for when importing modules. If a finder knows how to deal with a particular requested module then it returns a corresponding module spec and otherwise None
. Python has three different finders already registered which can be found in sys.meta_path
:
>>> import sys
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
The first one handles built-in modules, the second one frozen modules (some kind of "self-contained" Python scripts, see the wiki) and the last one handles everything which can be found on sys.path
. So if we modified sys.path
by appending '/home/project'
then it would be this finder which provides the corresponding spec.
Instead of modifying sys.path
we can register our own finder which uses the functionality of PathFinder
:
import importlib.machinery
class CustomFinder(importlib.machinery.PathFinder):
_path = ['/home/project']
@classmethod
def find_spec(cls, fullname, path=None, target=None):
return super().find_spec(fullname, cls._path, target)
Here we explicitly tell the PathFinder
to look into the /home/project
when importing modules.
We can register the finder as follows:
import sys
sys.meta_path.append(CustomFinder)
Then we can import the package aaa
which will be found by the CustomFinder
:
import aaa
For more information see PEP-302.
sys.path
We can modify sys.path
in order to put the required package on the path:
import sys
sys.path.append('/home/project')
import aaa
from aaa import whatever
# Optionally remove the added path.
sys.path.pop()
Appending this directory to the path won't block "existing" (e.g. built-in packages) with the same name due to the order of searching that is performed during an import.
__path__
You can add a local module aaa.py
(in fact you can add it to any location which is on the Python path) which contains the following code:
__path__ = ['/home/project/aaa']
Then you can perform import
statements which will refer to the package that you referred to with the __path__
variable:
from aaa import whatever
If you want to import aaa
you can mimic this by applying the same method one level up in the directory hierarchy. Add a local module project.py
(for example) with the following code:
__path__ = ['/home/project']
Then you can do
from project import aaa
which is very much similar import aaa
if aaa
was on the path (provided that no other module named project
has precedence on the path).
You can create a symlink that points to the package's directory. For example on Unix:
ln -s /home/project/aaa aaa
Then you can import the package via import aaa
, given you're executing this in the directory where you placed the symlink.
The symlink can also be created within your program via
import os
package = '/home/project/aaa'
target = os.path.split(package)[-1] # For example.
if not os.path.exists(target):
# `target_is_directory=True` is needed for Windows platform.
os.symlink(package, target, target_is_directory=True)
# Now import the package.
aaa = __import__(target)
setuptools
You can add a /home/project/setup.py
script which contains (for example) the following code:
from setuptools import setup
setup(
name='aaa',
packages=[
'aaa',
# Add any sub-packages that `aaa` contains here.
]
)
Then you can install the package via cd /home && pip install -e project
and you can readily import it in your other Python files:
import aaa
from aaa import whatever
By using virtualenv
you can keep your installed packages in a clean state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With