Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在名称空间dict中执行函数?_Python_Python 3.x - Fatal编程技术网

Python 如何在名称空间dict中执行函数?

Python 如何在名称空间dict中执行函数?,python,python-3.x,Python,Python 3.x,假设我有以下命令: In [6]: scope Out[6]: {'bar': <function bar>, 'foo': <function foo>} 我想运行bar(1),但它需要找到foo()。有没有办法在范围命名空间中运行bar(),以便它找到foo() 我不知道scopebar中需要哪个函数,因此我需要在scope命名空间中运行bar的通用方法。我没有的源代码,不能修改任何函数来接受dict 函数似乎有一个\uuuu closure\uuu属性,但它是不可

假设我有以下命令:

In [6]: scope
Out[6]: {'bar': <function bar>, 'foo': <function foo>}
我想运行
bar(1)
,但它需要找到
foo()
。有没有办法在
范围
命名空间中运行
bar()
,以便它找到
foo()

我不知道
scope
bar
中需要哪个函数,因此我需要在
scope
命名空间中运行
bar
的通用方法。我没有的源代码,不能修改任何函数来接受dict

函数似乎有一个
\uuuu closure\uuu
属性,但它是不可变的。还有一个
\uuuu globals\uuuu
属性,但它只指向
globals()
。我在上看到了一些答案,因此更新了
locals()
,但我想保持
locals()
不变

我在
scope
中尝试了
eval
,但在
foo
中得到了
namererror

In [12]: eval(scope['bar'](1), scope)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-12-f6305634f1da> in <module>()
----> 1 eval(scope['bar'](1), scope)

<string> in bar(x)

NameError: global name 'foo' is not defined
[12]中的
:eval(范围['bar'](1),范围)
---------------------------------------------------------------------------
NameError回溯(最近一次呼叫上次)
在()
---->1评估(范围['bar'](1),范围)
单位为bar(x)
NameError:未定义全局名称“foo”

是否有一些简单的方法我不知道?

一种方法是使用共享的全局字典创建新函数:

from types import FunctionType

def scopify(**kwargs):
    scoped = dict()
    for name, value in kwargs.items():
        if isinstance(value, FunctionType):
            scoped[name] = FunctionType(value.__code__, scoped, name)
        else:
            scoped[name] = value
    return scoped

scope = scopify(
    foo = lambda: baz,
    bar = lambda x: foo() + x,
    baz = 5,
)

>>> scope['foo']
5
>>> scope['bar'](10)
15
>>> scope['baz'] = 100
>>> scope['bar'](10)
110
使用
eval()。首先,它的第一个参数expression应该是一个字符串。其次,由于在这个表达式中引用了
scope
,并将其作为globals名称空间参数传递给
eval()
,因此需要将其添加到自身中

这说明了我的意思:

def foo():
    return 5

def bar(x):
    return foo() + x

scope = {'scope': {'bar': bar, 'foo':foo}}  # define self-referential scope
expression = "scope['bar'](42)"  # explicit reference to `scope`
print('eval({!r}, scope) returns {}'.format(expression, eval(expression, scope)))
但是,在这种特定情况下,让
eval()
直接在
scope
字典名称空间本身中查找
bar
的值会更简单(而不是通过
scope['scope']['bar']
):


函数是否位于可以导入的模块中?听起来有点像是在发明类。你能告诉我们你到底想做什么吗?+1。在我的例子中,martineau的答案更容易实现,但您指出了我一直在寻找的东西,即如何在不同的范围内“重新绑定”函数中的变量。文档中的FunctionType非常简单。@Capitalcuttle:您可以执行
help(types.FunctionType)
来获取更多关于它的信息(实际上它是一个名为
function
的类)。
def foo():
    return 5

def bar(x):
    return foo() + x

scope = {'scope': {'bar': bar, 'foo':foo}}  # define self-referential scope
expression = "scope['bar'](42)"  # explicit reference to `scope`
print('eval({!r}, scope) returns {}'.format(expression, eval(expression, scope)))
scope = {'bar': bar, 'foo':foo}
expression = 'bar(42)'
print('eval({!r}, scope) returns {}'.format(expression, eval(expression, scope)))