Gary Fixler
Gary Fixler

Reputation: 6038

Python - can a class act like a module?

I'm considering a package implementation set up like this:

wordproc
    __init__.py
    _generic.py
    gedit.py
    oofice.py
    word.py

_generic.py would have a class like this:

class WordProc (object):

    def __init__ (self):
        pass

    def createNewDoc (self):
        print "createNewDoc unimplemented in current interface"

    def getWordCount (self):
        print "getWordCount unimplemented in current interface"

    etc...

These could print out as shown, or raise errors. App-specific modules would just be copies of _generic.py with the WordProc classes deriving from _generic.WordProc. In this way, functionality could be implemented iteratively over time, with messages about unimplemented things simply raising alerts.

I'm imagining that __init__.py could look for the following things (listed in order) to figure out which module to use:

  1. a wordproc module variable
  2. a settings file in the path
  3. a wordproc environment variable
  4. a function that attempts to determine the environment
  5. a default in __init__.py (probably _generic.py)

I think 3 could be a function in each app's module, or these could go into folders with particularly named environment test scripts (e.g. env.py), and __init__.py could loop over them.

I'd like then in any libraries that want to use wordproc to simply be able to do this:

import wordproc as wp

wp.createNewDoc()
etc...

What I don't know is how to have wp resolve to the proper class in the proper module as determined by __init__.py. It doesn't make sense to do this:

import wordproc.gedit as wp

This destroys the point of having __init__.py determine which module in wordproc to use. I need something like class inheritance, but on the module level.

Upvotes: 2

Views: 1959

Answers (1)

Imran
Imran

Reputation: 91049

You can achieve your desired effect by writing __init__.py like this:

  1. Import the appropriate module first. See python docs on importlib.import_module or __import__ for help on dynamic imports.
  2. Instantiate the class from which you want to export methods
  3. Assign the instance methods to locals()
# import appropriate module as mod depending on settings, environment
# using importlib.import_module, or __import__

__all__ = []

_instance = mod.WordProc()
for attr in dir(_instance):
    if not attr.startswith('_') and callable(getattr(_instance, attr)):
        locals()[attr] = getattr(_instance, attr)

Upvotes: 2

Related Questions