Как я могу установить функциональную среду для функции Python?

1

В 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: была предоставлена ​​мотивация для этого.

Теги:
lua

5 ответов

5
Лучший ответ

Там 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 в песочнице.

  • 0
    Я использовал это для выполнения (короткого) файла , где нет списка параметров, чтобы получить хороший эффект.
2

Зачем вам это делать? Ваш код стал слишком читаемым? Просто передайте dict или struct с вашим "env" в функцию.

EDIT: прочитайте свою мотивацию. Первая часть, которую я не могу понять (написав сценарии lua в python, что это значит?), Вторая - неправильная. Это не способ ограничить окружающую среду. Например, вы можете import os.
Ограниченное выполнение - это сложная тема. Некоторые вещи, о которых я знаю:

1

Я не уверен, почему вы хотите это сделать, но вот один хакерский способ:

def foo():
    print bar
foo.func_globals['bar'] = 1
foo()

Предостережение: Это не то, что я рекомендую делать.

  • 0
    Спасибо за ответ. Некоторое время назад я сделал правку, объясняющую мою мотивацию для этого; может быть, вы знаете другой способ достижения этой цели?
  • 0
    execfile() , что вам нужно что-то вроде execfile() , где вы можете указать свои собственные значения для globals в вызове. Часть с ограниченным исполнением будет сложнее; вот некоторая справка о том, как работать, чтобы оживить это и заставить это работать .
Показать ещё 1 комментарий
0

Я не знаю никакого здравомыслящего способа сделать это. Просто используйте аргументы функции.

def f(blech):
    print(blech)

Если вы хотите, чтобы у него было много переменных, вставьте их в dict и передайте это.

def f(vars):
    print(vars['blech'])
    print(vars['fizz'])
0

У вас может получиться дополнительная функция, которая является блобом аргументов ключевого слова:

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)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню