如何在Python中导入变量包,就像在PHP中使用变量变量($$)一样?

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

我想根据用户选择的值导入一些包。

默认值为file1.py

1
from files import file1

如果用户选择file2,则应为:

1
from files import file2

在PHP中,我可以使用变量:

1
2
$file_name = 'file1';
include($$file_name);
1
2
$file_name = 'file2';
include($$file_name);

我怎样才能在python中做到这一点?


python没有直接等同于php的"变量"的特性。要获得"变量"的值(或任何其他表达式的值),可以使用eval函数。

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

但是,这不能用在import语句中。

可以使用__import__函数使用变量导入。

1
2
3
4
package ="os"
name ="path"

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

等于

1
from os import path as imported


旧线索,但我需要答案,所以其他人可能…

在python 2.7+中有一种更简单的方法可以做到这一点:

1
2
3
4
import importlib


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


正如Fredrik Lundh所说:

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.

顺便说一下,这是你最不感兴趣的方法。

简单地写(例如):

1
2
var ="datetime"
module = __import__(var)


让用户选择要导入的内容可能是一个非常糟糕的主意。包可以在导入时执行代码,因此您实际上允许用户在系统上任意执行代码!这样做更安全

1
2
3
4
5
6
7
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"

根据mattjbray的回答:

1
2
3
4
5
6
7
8
9
10
11
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.")

保存几行代码,并允许您以编程方式设置safe_names,或者加载多个模块并将它们分配给dict。