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?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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
Method 2
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)
Method 3
Anyway, here’s how these statements and functions work:
import Ximports 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 useX.nameto 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, soX.namedoesn’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, cimports the module X, and creates references in
the current namespace to the given objects. Or in other words, you can
now useaandbandcin your program.Finally,
X = __import__(‘X’)works likeimport 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)
Method 4
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.
Method 5
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"
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0