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

53

我想根据用户选择的值来导入某个包。

默认值为file1.py

from files import file1
如果用户选择file2,应该是这样的:
from files import file2

在 PHP 中,我可以使用变量变量(variable variables)来实现这个功能:

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

我该如何在Python中实现这个?


3
不要这样做!使用输入通常是不可信的,基于它进行盲目评估代码是一个坏主意。 - Noufal Ibrahim
谢谢,我现在正在使用默认设置进行导入。 - skargor
5个回答

81

Python没有与PHP的“变量变量”直接等价的功能。要获取“变量变量”的值(或任何其他表达式的值),您可以使用eval函数。

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

然而,这不能用于 import 语句。

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

package = "os"
name = "path"

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

等价于

from os import path as imported

46

虽然这是一个旧的帖子,但我需要答案,所以可能还有其他人需要...

在Python 2.7+中有一种更干净的方法:

import importlib


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

提示:你需要一个package.path.__init__.py文件才能使导入工作 - Bob Stein

39

正如Fredrik Lundh所说:

无论如何,以下是这些语句和函数的工作方式:

import X 导入模块X,并在当前命名空间中创建对该模块的引用。换句话说,在运行此语句后,您可以使用 X.name 来引用模块X中定义的内容。

from X import * 导入模块X,并在当前命名空间中创建对该模块定义的所有公共对象的引用(即没有以“_”开头的所有内容)。换句话说,在运行此语句后,您可以使用普通名称来引用模块X中定义的内容。但是X本身没有被定义,所以X.name不起作用。如果name已经被定义,则会被新版本替换。如果X中的name被更改为指向其他对象,则您的模块不会注意到。

from X import a, b, c 导入模块X,并在当前命名空间中创建对给定对象的引用。换句话说,您现在可以在程序中使用a, b, 和 c

最后,X = __import__('X') 类似于 import X,不同的是您需要 1) 将模块名称作为字符串传递,并且 2) 明确将其分配给当前命名空间中的变量。

顺便说一句,这就是您感兴趣的最后一个方法。

只需简单地编写(例如):

var = "datetime"
module = __import__(var)

6
基于 mattjbray 的回答:
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,或加载多个模块并将它们分配给字典。


5

让用户选择导入什么可能是一个非常糟糕的主意。软件包可以在导入时执行代码,因此您实际上允许用户在您的系统上任意执行代码!更安全的做法是采取以下措施:

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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接