I have the following directory structure:
root
/src
file1.py
file2.py
/libs
__init__.py
package.so
I wish to import package.so
within file1.py
.
I've tried the following import statements to no avail:
from .libs.package import func
from libs.package import func
from .libs import package
from libs import package
I want to avoid having to set PYTHONPATH
/ sys.path
.
Is there a simple way to do this? I assume the issue is due to the package being a shared object and not just a Python file - I don't have access to the source code for it.
Thanks, Adam
The most Pythonic way to import a module from another folder is to place an empty file named __init__.py into that folder and use the relative path with the dot notation. For example, a module in the parent folder would be imported with from .. import module .
We can use sys. path to add the path of the new different folder (the folder from where we want to import the modules) to the system path so that Python can also look for the module in that directory if it doesn't find the module in its current directory.
In order to import a module, the directory having that module must be present on PYTHONPATH. It is an environment variable that contains the list of packages that will be loaded by Python. The list of packages presents in PYTHONPATH is also present in sys. path, so will add the parent directory path to the sys.
If you are intent on not using sys.path.append
to import the file, I was able to do it using the following snippet in file1.py
:
import imp
import os
file = os.sep+os.path.join(*os.path.realpath(__file__).split(os.sep)[:-1]+['..','libs','package.so'])
package = imp.load_source('root.libs.package', file)
print package.a()
Which prints <root.libs.package.a instance at 0x101845518>
. Note that my package.so file is just a python file that defines a dummy class a
so that I could test importing it. From what I have read, I believe that replacing imp.load_source
with imp.load_dynamic
may be what you want.
Breaking it down:
os.path.realpath(__file__).split(os.sep)[:-1]
gets you the path to the directory the currently-running script is in, as a list of strings.
+['..','libs','package.so']
concatenates a list containing the parent directory (..
), the libs
directory, and your filename to that list, so that os.path.join will build the full path to the package.so
file.
os.path.join(*[that list])
unpacks the list elements into arguments to os.path.join
, and joins the strings with os.sep
. I also add a leading os.sep
since it is an absolute path.
imp.load_source
returns a module with the name root.libs.package
loaded from the file path.
This source was useful for writing this answer, and here are the docs for the imp
module, which you might also find useful.
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