我如何为Python函数设置函数环境?

在 Lua 中,有一个名为 setfenv() 的内置函数,它允许您为函数提供一些变量表,作为其环境。以下是一个使用它的示例:

foo = 1
def f():
    print(blech) #注意,没有一个名为 blech 的变量被定义。
variableTable = { 'blech': foo }
f.__globals__.update(variableTable)
f() #这能够正常工作并打印 1,因为blech已经被定义为变量表中foo的值

我这样做的动机是让用户能够在 Lua 中编写易于理解的脚本(他们可以编写 nullary 函数,可以简单地信任变量会出现在它们的脚本中)。它还提供了一种优雅的方法,可以排除我不希望他们出于安全原因使用的模块和函数(例如,如果您定义了一个不包含操作系统模块的变量表,更知识渊博的用户就无法恶意地使用它)。

我想在 Python 中能够实现相同的功能。Python 中是否有类似的功能?

原文链接 https://stackoverflow.com/questions/6143994

点赞
stackoverflow用户350351
stackoverflow用户350351

我不知道有什么正常的方法来做到那一点。只需使用函数参数。

def f(blech):
    print(blech)

如果你想要它有很多变量,把它们放在一个 dict 中,并传递它。

def f(vars):
    print(vars['blech'])
    print(vars['fizz'])
2011-05-26 19:31:42
stackoverflow用户18243
stackoverflow用户18243

这里有一个 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 沙盒模式

2011-05-26 19:33:03
stackoverflow用户538718
stackoverflow用户538718

我不确定你为什么想这样做,但是这里有一种hacky的方法:

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

注意:不建议这样做。

2011-05-26 19:33:30
stackoverflow用户738505
stackoverflow用户738505

为什么你要这么做呢?是因为你的代码变得太简单易读了吗?

只需将一个带有你的“env”(环境)的字典或一个结构体传递给函数即可。

编辑:阅读了你的动机。第一部分我无法理解(用Python编写lua脚本?那是什么意思?),第二部分是完全错误的。这不是限制环境的方式。首先,你仍然可以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
2011-05-26 19:40:10
stackoverflow用户129655
stackoverflow用户129655

你可以让你的函数接受一个额外的值,这个值是一堆关键字参数:

def printKeyValuePairs(preface, **kwargs):
    print preface + "\n"

    for k,v in kwargs.iteritems():
        print k + ": " + v + "\n"

# 使用示例
printKeyValuePairs("这是我的键值对:", One=1, Two=2, Three=3)
# 输出结果:
# 这是我的键值对:
# One: 1
# Two: 2
# Three: 3
# (注意,这些行的顺序可以任意排列......如果这很重要,可能要先进行排序)
2011-05-26 19:41:28