这个问题含糊不清,因为问题在于滥用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

10-05 18:10