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)))