Как я могу установить функциональную среду для функции Python? - PullRequest
1 голос
/ 26 мая 2011

В Lua есть встроенная функция 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's value in the variableTable

Моя мотивация для этого заключается в том, что это позволяет мне настроить платформу, чтобы пользователи могли писать простые для понимания скрипты на Lua (они могут писать нулевые функциии может просто доверять, что переменные будут там для них).Он также предоставляет элегантный метод исключения модулей и функций, которые я не хочу, чтобы они использовали по соображениям безопасности (например, если вы определяете переменную таблицу, в которой не определен модуль os, нет способа, которым более опытный пользователь мог бы использоватьэто злонамеренно).

Я хотел бы добиться того же в Python.Есть ли что-то подобное, что можно сделать в Python?

Ответы [ 5 ]

6 голосов
/ 26 мая 2011

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

2 голосов
/ 26 мая 2011

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

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

  1. Модуль с ограниченным Python - http://docs.python.org/library/restricted.html. Устаревший.
  2. Устаревшая вики-страница - http://wiki.python.org/moin/SandboxedPython. Ничего безумно полезного там нет.
  3. PyPy. Это, вероятно, путь. Документация по песочнице PyPy: http://codespeak.net/pypy/dist/pypy/doc/sandbox.html
1 голос
/ 26 мая 2011

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

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

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

0 голосов
/ 26 мая 2011

Вы можете сделать так, чтобы ваша функция принимала дополнительное значение, являющееся набором ключевых аргументов:

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)
0 голосов
/ 26 мая 2011

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

def f(blech):
    print(blech)

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

def f(vars):
    print(vars['blech'])
    print(vars['fizz'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...