4

I am working on project euler and wanted to time all of my code. What I have is directory of files in the form 'problemxxx.py' where xxx is the problem number. Each of these files has a main() function that returns the answer. So I have created a file called run.py, located in the same directory as the problem files. I am able to get the name of the file through command prompt. But when I try to import the problem file, I continue to get ImportError: No module named problem. Below is the code for run.py so far, along with the command prompt used.

# run.py
import sys
problem = sys.argv[1]
import problem         # I have also tired 'from problem import main' w/ same result

# will add timeit functions later, but trying to get this to run first
problem.main()

The command prompts that I have tried are the following: (both of which give the ImportError stated above)

python run.py problem001
python run.py problem001.py

How can I import the function main() from the file problem001.py? Does importing not work with the file name stored as a variable? Is there a better solution than trying to get the file name through command prompt? Let me know if I need to add more information, and thank you for any help!

David C
  • 1,898
  • 2
  • 16
  • 31
  • See this answer: http://stackoverflow.com/questions/6677424/how-do-i-import-variable-packages-in-python-like-using-variable-variables-i – OregonTrail Sep 26 '14 at 15:32

3 Answers3

2

You can do this by using the __import__() function.

# run.py
import sys
problem = __import__(sys.argv[1], fromlist=["main"])         # I have also tired 'from problem import main' w/ same result
problem.main()

Then if you have problem001.py like this:

def main():
    print "In sub_main"

Calling python run.py problem001 prints:

In sub_main

A cleaner way to do this (instead of the __import__ way) is to use the importlib module. Your run.py needs to changes:

import importlib
problem = importlib.import_module(sys.argv[1])

Alternatives are mentioned in this question.

Community
  • 1
  • 1
Andy
  • 49,085
  • 60
  • 166
  • 233
  • Thanks for providing multiple options, I like the clean way with use of importlib. Would that be the recommended way since it has been mentioned that __import__ is not recommended? – David C Sep 26 '14 at 15:45
  • Yes, importlib is a better option. – Andy Sep 26 '14 at 15:46
1

For sure! You can use __ import_ built-in function like __import__(problem). However this is not recommended to use, because it is not nice in terms of coding-style. I think if you are using this for testing purposes then you should use unittest module, either way try to avoid these constructions.

Regards

PaulOverflow
  • 1,091
  • 1
  • 10
  • 12
-1

You can use exec() trick:

    import sys
    problem = sys.argv[1] 
    exec('import %s' % problem)
    exec('%s.main()' % problem)
Dmitry
  • 111
  • 1
  • 10