0

This is my app structure using python 3.5

app
    __init__.py  # running the code from here
    module
        __init__.py
        test.py  # want access to this 
            ^-- test_function() is here
        test2.py # and this one too

I am full aware I can access test with the following. note I am running this using the following cmd python 3 /app/__init__.py need access to /app/module/test.py

from module import test
test.test_function()
# works

I can also import it into global scope (bad practice)

from module.test import test_function
# works

And I know i can also use

import module.test
# works

But what I would like to do is import the full module (or package sorry for my terminology)

I want to import the full package, example:

import module

module.test.test_function()

But I seem to get

AttributeError: module 'module' has no attribute 'test'

bonus question If importing the full package is not a good practice then I don't mind being explicit and using from module import test, please let me know.

PS I have tried adding imports in /app/module/__init__.py because it gets called during the import, but it seems that it doesn't work

I added import test in /app/module/__init__.py but when I try it test seems empty.

import module # module now has import test in its __init__
print(dir(module.test))
# ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']

As you can see it's missing test_function()

c3cris
  • 1,276
  • 2
  • 15
  • 37
  • I understand I am curious to import module and i get access to test and test2. I have already stated I know I can import individual ones. I am trying to import the full package. – c3cris Jul 11 '16 at 18:05
  • Why are your files (module) prefixed with `/` ? – styvane Jul 11 '16 at 18:08
  • Just visual for the directory structure. sorry for the confusion, I removed them – c3cris Jul 11 '16 at 18:08
  • You've tagged this Python 3, and Python 3 doesn't do automatic relative imports. `import test` will never refer to `module.test`; heck, the fact that you can import `module` as anything other than `app.module` suggests that you've configured your module path wrong. – user2357112 Jul 11 '16 at 18:22
  • 1
    Possible duplicate of [Loading all modules in a folder in Python](http://stackoverflow.com/questions/1057431/loading-all-modules-in-a-folder-in-python) – Bahrom Jul 11 '16 at 18:23
  • @Bahrom question about python 3, it has some difference with python 2 – outoftime Jul 11 '16 at 19:10

1 Answers1

1

Few additional thoughts to Loading all modules in a folder in Python

$ tree
.
├── mod
│   ├── __init__.py
│   ├── test.py
└── run.py

__init__.py

# to import all objects use star '*' instead of name literals
from mod.test import hello_world

test.py

def hello_world():
    print('Hello World!')

run.py

import mod

if __name__ == '__main__':
    mod.hello_world()

Result

$ python run.py 
Hello World!

You can import any modules, sub modules or anything else to make it part of "public" interface of package.

UPD: I'm highly recomend you to read packages topic from documentation. As it sad

It’s important to keep in mind that all packages are modules, but not all modules are packages. Or put another way, packages are just a special kind of module. Specifically, any module that contains a __path__ attribute is considered a package.

You can think in this way: when you importing module, you are loading all objects from module_name.py file, but when you importing package you are loading __init__.py file.

Packages usually contain so called public interface, which contains only reusable components related to this package without helper functions, etc. In this way packages hides some code from outer scope (where it will be used) while importing.

Community
  • 1
  • 1
outoftime
  • 715
  • 7
  • 21
  • So I should use 'from module import *'? – c3cris Jul 11 '16 at 18:27
  • @c3cris I'm editing answer right now. Yes it can help, but in this way all helper functions, etc., will be in public interface of package and this is not good in most cases. – outoftime Jul 11 '16 at 18:32
  • Ok i will check later for your revised answer :) – c3cris Jul 11 '16 at 18:45
  • I get ImportError: cannot import name 'test_function' when I run `python3 run.py` – c3cris Jul 11 '16 at 18:54
  • 1
    Never mind i got it. In the `mod/__init__.py` I need to add `from . import test` because it's a https://docs.python.org/3/tutorial/modules.html#intra-package-references – c3cris Jul 11 '16 at 18:59
  • @c3cris I prefer explicit importing with absolute names instead of relative. – outoftime Jul 11 '16 at 19:09
  • I cannot seem to get the sub module `mod` to load test.py with absolute path if I import it from run.py – c3cris Jul 11 '16 at 19:14