Import python packages that have similar internal module names, by full path
Question: 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.


Answer: 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.

