0

file1.py

def foo(x):
    print(x)

file2.py

def foo(x):
    print(x)

main.py

import file1
import file2
#User inputs either file1 or file2
variable = input()
#--
#TODO: A way to call the correct module so either file1.foo('test') or file2.foo('test')
#--

The code explains what I want to achieve but I can't find a solution to my problem, I have been looking for a couple of hours. Maybe I am just looking in the wrong place or looking with the wrong keywords. Most of the solutions online are solutions for the opposite problem. (constant module, variable function)

Please keep in mind that this is a simplified version of my actual code. In this example I could just solve it with an if-statement but in my actual project I have around 30 possible modules that could be called so it wouldn't be tidy to fix it with an if-statement.

Thanks in advance!

  • I'd suggest that an explicit `if` (or using a dictionary to store the functions against string keys, or something else of that ilk) _is_ the "tidy" way of doing things. It will make your code much more explicit and less surprising than using reflection to turn a string into a module reference, or using `importlib`. – JMAA Sep 07 '19 at 19:06
  • At first my goal was to keep it as compact as possible but I may change it to a dict. Just to improve readability. –  Sep 07 '19 at 19:18

2 Answers2

3

Perhaps you're looking for __import__?

file = __import__(input())
file.foo()

A way without __import__ would be to use a dictionary:

import file1
import file2

modules = {'file1': file1,
           'file2': file2}
modules[input()].foo()
Primusa
  • 13,136
  • 3
  • 33
  • 53
  • Unless you really know what you're doing I'd avoid using `__import__` or `importlib` at all, there are almost always cleaner less-error-prone ways to achieve the same thing – JMAA Sep 07 '19 at 19:02
  • This fixed my problem, thank you! I'll accept your answer as soon as the timer allows me to :) –  Sep 07 '19 at 19:04
  • @DriesAugustyns Glad to help :) – Primusa Sep 07 '19 at 19:05
2

You can use an additional foo variable that refers to either file1.foo or file2.foo based on the input, and then just call foo later:

if variable == 'file1':
    foo = file1.foo
else:
    foo = file2.foo

foo('test')

In case of multiple modules, you can use importlib.import_module for this:

import importlib

mod = importlib.import_module(variable)

mod.foo('test')
DjaouadNM
  • 22,013
  • 4
  • 33
  • 55
  • 1
    "In this example I could just solve it with an if-statement but in my actual project I have around 30 possible modules that could be called so it wouldn't be tidy to fix it with an if-statement." – Sayse Sep 07 '19 at 19:03
  • In that case I would still need a massive if to compare all modules –  Sep 07 '19 at 19:05
  • @DriesAugustyns In that case you can use `importlib`, check the edit. – DjaouadNM Sep 07 '19 at 19:08
  • Great edit! importlib seems to be a great solution as well. –  Sep 07 '19 at 19:14