这个问题含糊不清,因为问题在于滥用Python是有充分理由的。
假设我将python作为程序输入:
scf() # produces F,C that are somehow available globally
ci() # uses F,C
问题是,
scf
可以修改调用方的模块吗?第二种情况:
F,C = scf() # F,C are not set globally.
因此,基本上要么捕获值(x)要么全局设置它。
怎么做到呢?
最佳答案
分享这个让我感到不舒服,但是在CPython中,您可以更改堆栈框架:
import sys
def scf():
frame = sys._getframe(1) #caller's frame (probably)
frame.f_globals['F'] = 'F' #add/overwrite globals
frame.f_globals['C'] = 'C'
def ci():
print F, C
scf()
ci() # prints 'F C'
但是,为什么需要隐式更改调用者的名称空间?设计不良的脸颊。
scf()
应该返回事物,而ci()
应该接受那些事物作为参数。如果您对自己的工作有更多的了解,也许我们可以建议更好的方法。更新资料
因此,您正在尝试维护外部执行的字符串(Python程序)之间的某些状态。这在Python中很简单:只需保留一个显式的locals和globals命名空间,然后在
exec
and friends的调用之间传递它。s1 = """
foo = 'bar'
"""
s2 = """
def myImpureFunction():
global foo
foo = 1
myImpureFunction()
"""
lvars, gvars = {}, {}
exec s1 in lvars, gvars
print gvars
exec s2 in lvars, gvars
print gvars
也许为了保持某种理智,您可以向用户保证在运行之间将保留一个特殊的变量:
s1 = """
stash.foo = 'bar'
"""
s2 = """
def myImpureFunction():
stash.foo = 'foo'
myImpureFunction()
"""
from types import ModuleType
lvars = {'stash': ModuleType('stash')}
exec s1 in lvars
print lvars['stash'].foo
exec s2 in lvars
print lvars['stash'].foo