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

ska*_*gor 39 python variables variable-variables

我想导入一些包,具体取决于用户选择的值.

默认为file1.py:

from files import file1
Run Code Online (Sandbox Code Playgroud)

如果用户选择file2,它应该是:

from files import file2
Run Code Online (Sandbox Code Playgroud)

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

$file_name = 'file1';
include($$file_name);
Run Code Online (Sandbox Code Playgroud)
$file_name = 'file2';
include($$file_name);
Run Code Online (Sandbox Code Playgroud)

我怎么能用Python做到这一点?

小智 58

Python没有一个直接等同于PHP的"变量变量"的功能.要获得"变量变量"的值(或任何其他表达式的值),您可以使用该eval函数.

foo = "Hello World"
print eval("foo")
Run Code Online (Sandbox Code Playgroud)

但是,这不能用于import声明中.

可以使用该__import__函数使用变量导入.

package = "os"
name = "path"

imported = getattr(__import__(package, fromlist=[name]), name)
Run Code Online (Sandbox Code Playgroud)

相当于

from os import path as imported
Run Code Online (Sandbox Code Playgroud)


小智 38

老线程,但我需要答案,所以其他人仍然可能......

在Python 2.7+中有一种更简洁的方法:

import importlib


my_module = importlib.import_module("package.path.%s" % module_name)
Run Code Online (Sandbox Code Playgroud)


Gan*_*ndi 31

正如Fredrik Lundh所述:

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

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

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

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

最后,X = __import__(‘X’)类似的工作import X,1)将模块名称作为字符串传递,2)显式将其分配给当前命名空间中的变量.

顺便说一句,这是你感兴趣的最后一种方法.

只需写(例如):

var = "datetime"
module = __import__(var)
Run Code Online (Sandbox Code Playgroud)


mat*_*ray 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"
Run Code Online (Sandbox Code Playgroud)


sle*_*anc 5

基于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.")
Run Code Online (Sandbox Code Playgroud)

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