假设我有以下命令:
In [6]: scope
Out[6]: {'bar': <function bar>, 'foo': <function foo>}
Run Code Online (Sandbox Code Playgroud)
并且foo和bar是:
def foo():
return 5
def bar(x):
return foo() + x
Run Code Online (Sandbox Code Playgroud)
我想跑bar(1),但还需要找到foo()。bar()有没有办法在名称空间中运行scope以便找到foo()?
我不确切知道需要哪个函数,所以我需要一个在命名空间中scope bar运行的通用方法。我没有源代码,也无法修改任何一个函数来接受字典。barscope
看起来函数有一个__closure__属性,但它是不可变的。还有一个__globals__属性,但它仅指向globals(). 我已经看到了有关该更新的一些答案,locals()但我想保持locals()不变。
我尝试了evalin scope,但得到了NameErrorfor foo:
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
Run Code Online (Sandbox Code Playgroud)
我缺少一些简单的方法吗?
使用eval()会起作用,但是您尝试使用它的方式存在两个问题。对于初学者来说,它的第一个参数expression应该是一个字符串。其次,由于您scope在该表达式中引用并将其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)))
Run Code Online (Sandbox Code Playgroud)
然而,在这种特定情况下,直接在字典命名空间本身中eval()查找 的值(而不是 via )会更简单:barscopescope['scope']['bar']
scope = {'bar': bar, 'foo':foo}
expression = 'bar(42)'
print('eval({!r}, scope) returns {}'.format(expression, eval(expression, scope)))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
909 次 |
| 最近记录: |