3

I am making a program where a user can save a file, load it back, and name the file the way they want.

How can I dynamically import all attributes of that module?

E.g. something like the pseudocode below:

module_name = input()
from module_name import *

Assume module_name ends with ".py".
I am using python 3.5.

user
  • 5,370
  • 8
  • 47
  • 75
  • It sounds like you're looking for `__import__`: http://stackoverflow.com/questions/13598035/importing-a-module-when-the-module-name-is-in-a-variable – happydave Nov 25 '16 at 03:42
  • exec('import {}'.format(the_input)) -- quick and dirty but not very safe unless you filter 'the_input' (for instance, by making sure it is an valid python identifier and not a keyword) and send your own dicts for locals & globals. – Emanuel Landeholm Nov 25 '16 at 22:04
  • @EmanuelLandeholm There is no way to make the input safe. – user Nov 25 '16 at 22:04
  • @Fermi paradox Probably true. This is what I do: https://github.com/elandeholm/pimp/blob/master/pimp.py It's safe enough for my own usage but I wouldn't ship code like that. – Emanuel Landeholm Nov 25 '16 at 22:06
  • @EmanuelLandeholm Offtopic: Was trying to find a flaw in the linked rep, but have never used argv or bash before. What was surprising though is that i can name a file `print('arbitrary code can be run');file_1.py`. Perhaps it would make an interesting question to post that code and ask for ways to abuse it. "eval"-type questions tend to get popular sometimes. – user Nov 26 '16 at 09:11
  • 1
    eval/exec are always ripe for abuse. I found a sneaky way to call eval() from an online python REPL (which shall remain unnamed), mailed the author and he got back to me and basically said "there is no practical way to prevent eval". I was dumbstruck at their defeatist attitude. Sure, their REPL was fortified in other ways (monkeypatching, filtered imports) but I'm quite positive there's a way to do evil stuff with eval() in that REPL. – Emanuel Landeholm Nov 26 '16 at 09:23

1 Answers1

3

This sounds like a terrible idea, but here is an example of loading math module and using some of its functions.

import importlib

my_module = importlib.import_module('math')    
globals().update(my_module.__dict__)

print(globals())
print(sin(pi/2))

(Code improvements by jmd_dk)


It sounds like a bad idea because from x import * will import everything and potentially overwrite local attributes.

Additionally, there are most likely more clear ways to achieve your goals by using a dictionary.

Community
  • 1
  • 1
user
  • 5,370
  • 8
  • 47
  • 75