В Lua существует функция built-, называемая setfenv()
, которая позволяет вам снабжать таблицу переменных в качестве среды для функции. Вот пример, который использует его:
foo = 1
function f()
print(blech) --Note that no variable named blech has been defined.
end
variableTable = {blech = foo}
setfenv(f, variableTable)
f() -- This will work and print 1, because blech has been defined as foo value in the variableTable
Моя мотивация для этого заключается в том, что он позволяет мне создать платформу, чтобы пользователи могли писать скрипты easy- to- в Lua (они могут писать нулевые функции и могут просто доверять тому, что для них будут переменные). Он также предлагает элегантный метод исключения модулей и функций, которые я не хочу использовать для их использования по соображениям безопасности (т.е. Если вы определяете таблицу переменных, которая не имеет определенного модуля os, то нет возможности использовать более опытный пользователь это злонамеренно).
Я хотел бы иметь возможность добиться того же самого в Python. Есть ли что-то подобное в Python?
EDIT: была предоставлена мотивация для этого.
Там exec
:
def foo():
print bar
exec foo.func_code in {"bar": "baz"}
Это не особенно хороший стиль (я бы даже сказал, что это особенно плохо). Это делает реализацию foo
трудной для понимания, поскольку она полагается на знание о том, каким образом она будет называться. Вместо этого передайте аргументы функции.
Это не обеспечивает какой-либо меры безопасности. В первом приближении Python не включает ограниченные возможности выполнения. Ничто не мешает пользователю использовать это определение foo:
def foo():
import os
os.system("rm -rf /")
Просто потому, что вы не поставляли os
в сопоставлении, это не значит, что они не могут получить его сами. Если вам действительно нужно ограниченное исполнение, вы можете захотеть придерживаться Lua или, по крайней мере, расследовать PyPy в песочнице.
Зачем вам это делать? Ваш код стал слишком читаемым? Просто передайте dict или struct с вашим "env" в функцию.
EDIT: прочитайте свою мотивацию. Первая часть, которую я не могу понять (написав сценарии lua в python, что это значит?), Вторая - неправильная. Это не способ ограничить окружающую среду. Например, вы можете import os
.
Ограниченное выполнение - это сложная тема. Некоторые вещи, о которых я знаю:
Я не уверен, почему вы хотите это сделать, но вот один хакерский способ:
def foo():
print bar
foo.func_globals['bar'] = 1
foo()
Предостережение: Это не то, что я рекомендую делать.
execfile()
, что вам нужно что-то вроде execfile()
, где вы можете указать свои собственные значения для globals
в вызове. Часть с ограниченным исполнением будет сложнее; вот некоторая справка о том, как работать, чтобы оживить это и заставить это работать .
Я не знаю никакого здравомыслящего способа сделать это. Просто используйте аргументы функции.
def f(blech):
print(blech)
Если вы хотите, чтобы у него было много переменных, вставьте их в dict
и передайте это.
def f(vars):
print(vars['blech'])
print(vars['fizz'])
У вас может получиться дополнительная функция, которая является блобом аргументов ключевого слова:
def printKeyValuePairs(preface, **kwargs):
print preface + "\n"
for k,v in kwargs.iteritems():
print k + ": " + v + "\n"
# usage
printKeyValuePairs("Here are my key-value pairs:", One=1, Two=2, Three=3)
# prints:
# Here are my key-value pairs:
# One: 1
# Two: 2
# Three: 3
# (note that the above lines could be ordered any which way... might want to
# sort first if it matters)