In my project I need to import two external packages from two different full paths.
When I had only one external package, I added its path to sys.path
and it worked, I could do that for both of the package but unfortunately both packages have similar internal modules, so if I add them both to sys.path
they will cross import internal modules from each other.
To clarify, the folder structure of the packages looks like this:
package1\
__init__.py
settings.py
a.py # does 'import settings'
package2\
__init__.py
settings.py
b.py # also does 'import settings'
How can I import both packages without conflicts?
I've tried using imp.load_source
but it looks like it can only load files.
Edit: When I only had one package, I would import from it using the following code:
sys.path.insert(1, "PATH TO PACKAGE1")
from package1 import a
Edit 2:
The directory structure of the packages is actually much more complicated than the one in the one above, and contains hundreds of files. There are also internal modules that may import settings.py
, for example:
package1\
__init__.py
settings.py
internal_module\
__init__.py
a.py # does 'import settings'
This means I can't assume that a.py
and settings.py
are in the same directory.
if you import settings in package1/a.py, python will look for settings.py first in the current director i.e package1 and not package2 even if they both are in sys.path. So even if you import as (based on the directory structure you have shown above) assuming you have added pacakge1 and package2 in sys.path:
from package1 import a
from package2 import b
This is going to work without any problem and a.py will import setttings module from package1 and b.py will import the settings from package2.
If you have modules with same name both in package1 and package2, then the good way to do the imports is
import package1.settings as package1_settings
import package2.settings as package2_settings
Now you can access your variables in package1_settings and package2_settings as
package1_settings.var1
package2_settings.var1
All this will work if you have added the absolute path to "package1" and "package2" to sys.path:
sys.path.append(os.path.abspath("package1")) # something like that
Here is a little experiment I did:
The package structure is:
package1
__init__.py
a.py
settings.py
package2
__init__.py
b.py
settings.py
test.py
a.py
import settings
def print_a():
print settings.a
b.py
import settings
def print_a():
print settings.a
package1.settings.py
a = "settings.py in package1"
package2.settings.py
a = "settings.py in package2"
test.py
import sys
import os
dir_name = os.path.abspath(os.path.dirname("__file__"))
package1_path = os.path.join(dir_name, "package1")
package2_path = os.path.join(dir_name, "package2")
sys.path.append(package1_path)
sys.path.append(package2_path)
from package1 import a
from package2 import b
a.print_a()
b.print_a()
Output of "python test.py"
>>> python test.py
settings.py in package1
settings.py in package2
Edit For such cases, the good practice is
Always reference your imports from your top level package
You will add package1 and package2 to your sys.path and reference all your imports from them.
import package1.settings as package1_settings
import package1.internal_module.a as package1_internal_module_a #give a shorter name
import package1.internal_module.other_module.settings as package1_internal_other_settings
This way it can be ensured that your import paths never collide with each other. One other advantage of this is portability of your package. Tomorrow if you decide to change the location of package1, all the code in your package1 would just work because all your imports are referenced from package1.
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