简体   繁体   中英

Python - namespace conflict if deployed to two different paths

I have a top level namespace, working like an organization namespace. Let's name that myorg , where it's __init__.py looks like this :

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

This is being deployed under /opt where our Python lives, along with some developed python libraries - let's say mylib .

So on a Python2.7 interpreter this works

>>> import myorg
>>> import myorg.mylib

Apart from the libraries, we have some client code that gets deployed elsewhere in the system, in /bb/bin . For example for clientA I can have :

>>> import sys
>>> sys.path.append('/bb/bin')
>>> import clientA

and this works.

However, due to how our code is structured, we share the same namespace myorg - so clientB is also under myorg and there is a /bb/bin/myorg/__init__.py as well, with the same contants as the one in the /opt path.

Question is :

why this one works -

>>> import sys
>>> sys.path.append('/bb/bin')
>>> import myorg.clientB

but this one doesn't :

>>> import myorg # import from /opt location
>>> import sys
>>> sys.path.append('/bb/bin')
>>> import myorg.clientB # it should find the module under myorg in /bb/bin
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named clientB

This also does not work :

>>> import myorg.mylib
>>> import sys
>>> sys.path.insert(0,'/bb/bin') # Adding the /bb/bin path first
>>> import myorg.clientB
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named clientB

So, it's like the myorg namespace, if imported from the /opt then it will always try and find the modules under there.

Why is that? Can someone explain how to fix that issue and why that is happening?

I also dont understand why prepending that /bb/bin to my path does not make it work.

TL;DR

My intended behaviour or what I was hoping for is :

  • search in the /opt/ for the module
  • if not found go to other eg /bb/bin

This works on first case, but it seems if myorg has been imported from /opt then it only looks for modules inside there.

That's because "myorg" is already loaded - python loads modules/packages only once. If you load myorg (from /opt) first (or any sub-module as Python loads all "steps" of the import), then any myorg.something will be relative to that.

Can you try import as ? PEP describing it .

If I understand how python works, this should work:

import myorg as whateveryouwant # import from /opt location
import sys
sys.path.append('/bb/bin')
import myorg.clientB

EDIT: Noticed your comment that it doesn't work. :(

You can also try just appending /bb/bin/myorg and then importing just clientB instead of myorg.clientB . It's ugly but should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM