7O'clock
7O'clock

Reputation: 41

How can I achieve override a function call in the middle of another function?

I am writing a Python3 program, in which I need to be able to override some method on the fly. My folder structure is more like:

./
prog.py
methods/
  add.py
  minus.py

In prog.py I want to call a calc() function which is defined both in add.py and minus.py. I wish that the code can work as if:

def prog('foo'):
    from method.foo import calc
    calc()

But importing in the middle of a function seems awful and might slow down the whole program. Is there any workaround that can achieve the same effect?

I am trying to be flexible so that I can add more methods later on, so I avoid if statements and import all the modules at once.

Upvotes: 0

Views: 504

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121584

You have 2 options:

  • Import the modules, and use the module name with calc attributes.
  • Import the calc functions under alternate names with from ... import ... as

Either way, I'd store the function references in a dictionary, rather than use if .. elif to pick one.

The first approach

from method import add
from method import minus

calc_functions = {
    'add': add.calc,
    'minus': minus.calc,
}

def prog(method):
    return calc_functions[method]()   

or the second:

from method.add import calc as addition
from method.minus import calc as subtraction

calc_functions = {
    'add': addition,
    'minus': subtraction,
}

def prog(method):
    return calc_functions[method]()   

If you needed to import modules dynamically, then use importlib.import_module(), no need to worry about name clashes:

import importlib

def prog(method):
    try:
        calc_module = importlib.import_module('method.' + method)
    except ModuleNotFoundError:   # or ImportError in Python < 3.6
        raise ValueError('No such method {!r}'.format(method))
    return calc_module.calc()

    return calc_functions[method]()   

Upvotes: 5

Related Questions