Question

Alright, so I have a file with controllers for various pages of a site. Let's say the following structure.

/controllers
    /login_controller.py
    /main_controller.py
    /and_so_forth

I know that you can dynamically load all defined symbols in the folder controllers by using this snipped in the __init__.py:

__all__ = []

import pkgutil
import inspect

for loader, name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(name).load_module(name)

    for name, value in inspect.getmembers(module):
        if name.startswith('__'):
            continue

        globals()[name] = value
        __all__.append(name)

The thing is, I do like qualified imports. So say each controller file has one controller function defined. Is there any way to achieve the behaviour with __init__.py magic so that when I do:

import controllers

I can call the functions as

controllers.controller_function_name()

instead of:

controllers.module_name.controller_function_name()

? Removing the middle-man. Essentially, have it behave as if it was just a module.

Is there any way to do this?

Était-ce utile?

La solution

If I understand you right, your code already lets you do what you want to do.

When you do globals()[name] = value, you create a global variable in __init__.py. Global variables in __init__.py are what determines what is available under the package namespace. So if in your code you wind up creating a variable some_controller in __init__.py, then you will be able to do controllers.some_controller.

__all__ only affects what is imported when you use from module import *. By modifying __all__, you are affecting what will happen if you do from controllers import *, but you're not affecting what will be available under controllers if you just do import controllers.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top