How do I import variable packages in Python like u

2019-01-10 11:52发布

问题:

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?

回答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


回答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)


回答3:

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)


回答4:

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"


回答5:

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.