How do I import variable packages in Python like using variable variables ($$) in PHP?

PythonVariablesVariable Variables

Python Problem Overview


I want to import some package depending on which value the user chooses.

The default is file1.py:

from files import file1

If user chooses file2, it should be :

from files import file2

In PHP, I can do this using variable variables:

$file_name = 'file1';
include($$file_name);

$file_name = 'file2';
include($$file_name);

How can I do this in Python?

Python Solutions


Solution 1 - Python

Python doesn't have a feature that's directly equivalent to PHP's "variable variables". To get a "variable variable"'s value (or the value of any other expression) you can use the eval function.

foo = "Hello World"
print eval("foo")

However, this can't be used in an import statement.

It is possible to use the __import__ function to import using a variable.

package = "os"
name = "path"

imported = getattr(__import__(package, fromlist=[name]), name)

is equivalent to

from os import path as imported

Solution 2 - Python

Old thread, but I needed the answer, so someone else still might...

There's a cleaner way to do this in Python 2.7+:

import importlib


my_module = importlib.import_module("package.path.%s" % module_name)

Solution 3 - Python

As Fredrik Lundh states:

> Anyway, here’s how these statements and functions work: > > import X imports the module X, and creates a reference to that module > in the current namespace. Or in other words, after you’ve run this > statement, you can use X.name to refer to things defined in module X. > > from X import * imports the module X, and creates references in the > current namespace to all public objects defined by that module (that > is, everything that doesn’t have a name starting with “_”). Or in > other words, after you’ve run this statement, you can simply use a > plain name to refer to things defined in module X. But X itself is not > defined, so X.name doesn’t work. And if name was already defined, it > is replaced by the new version. And if name in X is changed to point > to some other object, your module won’t notice. > > from X import a, b, c imports the module X, and creates references in > the current namespace to the given objects. Or in other words, you can > now use a and b and c in your program. > > Finally, X = __import__(‘X’) works like import X, with the difference > that you 1) pass the module name as a string, and 2) explicitly assign > it to a variable in your current namespace.

And by the way that's the last one method that you're intrested in.

Simply write (for example):

var = "datetime"
module = __import__(var)

Solution 4 - Python

Basing myself on mattjbray's answer:

from importlib import import_module

# lookup in a set is in constant time
safe_names = {"file1.py", "file2.py", "file3.py", ...}

user_input = ...

if user_input in safe_names:
    file = import_module(user_input)
else:
    print("Nope, not doing this.")

Saves a few lines of code, and allows you to set safe_names programmatically, or load multiple modules and assign them to a dict, for example.

Solution 5 - Python

It's probably a very bad idea to let the user choose what to import. Packages can execute code on import, so you're effectively allowing a user to arbitrarily execute code on your system! Much safer to do something like

if user_input == 'file1.py':
  from files import file1 as file
elif user_input == 'file2.py':
  from files import file2 as file
else:
  file = None
  print "Sorry, you can't import that file"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionskargorView Question on Stackoverflow
Solution 1 - PythonJeremyView Answer on Stackoverflow
Solution 2 - PythonDan CopelandView Answer on Stackoverflow
Solution 3 - PythonGandiView Answer on Stackoverflow
Solution 4 - PythonsleblancView Answer on Stackoverflow
Solution 5 - PythonmattjbrayView Answer on Stackoverflow