0

I have this directory structure obtained with setuptools:

root/
    A/
      __init__.py
      1.py
      2.py
    B/
      __init__.py
      3.py
    __init__.py

the package section is the following:

packages=['root', 'root.A', 'root.B', ],

to import the content of the inner .py files i use:

from root.A import 1
from root.B.3 import a_func

now, if i wanted to import a_func directly from the root module, i would add the following line to the init file in the root directory

# to allow root.a_func access
from .B.3 import a_func

but is there a way to import an entire module instead of a single specific item (while preserving the same directory structure) ?

from root import 1
from root.3 import a_func

in other words, is it possible to hide the access of an intermediate level module during import?

I have already tried to add the following lines to the init file in the root dir, but it does not work.

from .A import *
from .B import *

any suggestion?

martineau
  • 119,623
  • 25
  • 170
  • 301
darkpirate
  • 712
  • 3
  • 10
  • 27

1 Answers1

1

Modifying the __path__ variable might help.


# root/__init__.py
import os
__path__.append(os.path.join(os.path.dirname(__file__), 'A'))
# root/A/__init__.py
# empty
# root/A/one.py
def first_func():
    print("first_func belongs to:", __name__, "in:", __file__)

This allows to do the following:

$ python3 -c "from root import one; one.first_func()"
first_func belongs to: root.one in: /home/sinoroc/workspace/root/.venv/lib/python3.6/site-packages/root-0.0.0.dev0-py3.6.egg/root/A/one.py

As well as:

$ python3 -c "from root.A import one; one.first_func()"
first_func belongs to: root.A.one in: /home/sinoroc/workspace/root/.venv/lib/python3.6/site-packages/root-0.0.0.dev0-py3.6.egg/root/A/one.py

See:

sinoroc
  • 18,409
  • 2
  • 39
  • 70
  • this is what i was looking for. Really appreciated. I wonder if it's considered "un-pythonic" after PEP 420... – darkpirate Sep 11 '19 at 13:13
  • I haven't really looked into _PEP 420_ nor _namespace packages_. I guess it depends on your actual use case, if you want to have code living in `root` and/or in `root.A` as well as in `root.A.one` aka `root.one`. As long as you document thoroughly your packages for your users, I would say anything goes. – sinoroc Sep 11 '19 at 13:36