Как мне импортировать переменные пакеты в Python, например, используя переменные переменные ($$) в PHP? - PullRequest
36 голосов
/ 13 июля 2011

Я хочу импортировать некоторый пакет в зависимости от того, какое значение выберет пользователь.

По умолчанию file1.py:

from files import file1

Если пользователь выбирает file2, оно должно быть:

from files import file2

В PHP я могу сделать это, используя переменные переменные :

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

Как я могу сделать это в Python?

Ответы [ 5 ]

54 голосов
/ 13 июля 2011

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
35 голосов
/ 07 мая 2013

Старая тема, но мне нужен был ответ, так что кто-то еще мог бы ...

Есть более понятный способ сделать это в Python 2.7 +:

import importlib


my_module = importlib.import_module("package.path.%s" % module_name)
28 голосов
/ 13 июля 2011

Как Фредрик Лунд заявляет:

В любом случае, вот как эти операторы и функции работают:

import X импортирует модуль X и создаетссылка на этот модуль в текущем пространстве имен.Или, другими словами, после выполнения этого оператора вы можете использовать X.name для ссылки на вещи, определенные в модуле X.

from X import * импортирует модуль X и создает ссылки в текущем пространстве имен длявсе открытые объекты, определенные этим модулем (то есть все, что не имеет имени, начинающегося с «_»).Другими словами, после выполнения этого оператора вы можете просто использовать простое имя для ссылки на вещи, определенные в модуле X. Но сам X не определен, поэтому X.name не работает.И если имя уже было определено, оно заменяется новой версией.И если имя в X будет изменено, чтобы указывать на какой-либо другой объект, ваш модуль не заметит.

from X import a, b, c импортирует модуль X и создает ссылки в текущем пространстве имен на заданные объекты.Или, другими словами, теперь вы можете использовать a и b и c в вашей программе.

Наконец, X = __import__(‘X’) работает как import X с той разницей, что вы 1) передать имя модуля в виде строки и 2) явно присвоить его переменной в текущем пространстве имен.

И, кстати, это последний метод, который вас интересует.

Просто напишите (например):

var = "datetime"
module = __import__(var)
4 голосов
/ 13 июля 2011

Вероятно, очень плохая идея позволить пользователю выбирать, что импортировать.Пакеты могут выполнять код при импорте, поэтому вы фактически позволяете пользователю произвольно выполнять код в вашей системе!Намного безопаснее сделать что-то вроде

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"
3 голосов
/ 21 ноября 2013

Основываясь на ответе 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 или загружать несколько модулей и присваивать их дикту,например.

...