python 在哪里存储导入函数的全局范围变量?

Where does python store an imported function's global scope variables?

我今天正在研究 python 示波器并做了一些实验。 而且我发现了一个有趣的现象。通过在导入函数中调用 exec("global var; var = value") 。我可以将此值存储在未知的地方。稍后我可以使用 import module; print(module.var) 检索它。请看下面的代码:

# temp.py
def str_to_global_var(string, obj):
    command_1 = 'global %s; %s=%r' % (string, string, obj)
    exec(command_1)



# script.py
from copy import copy
from temp import str_to_global_var

cur_global = copy(globals())
str_to_global_var('x', 6)

new_global = globals()

print(set(new_global.keys()) - set(cur_global.keys()))

d2 = copy(new_global)
d1 = copy(cur_global)

del d2['cur_global']
del d2['new_global']

print('Compare d2==d1: ', d2 == d1)
print("'x' in new_global: ",'x' in new_global)

import temp
print("temp.x:", temp.x)



# Interpreter running result
>>> ipython3 script.py

{'new_global', 'cur_global'}
Compare d2==d1:  True
'x' in new_global:  False
temp.x: 6

我在使用 str_to_global_var 函数之前和之后对 script.py 的 globals() 进行了浅拷贝(深拷贝将失败)。它们在删除 2 个不相关的标识符 "new_global" 和 "cur_global" 后比较相等,所以说在浅拷贝级别,解释器认为在使用导入后 script.py 的全局范围内没有任何变化str_to_global_var 函数,我们都知道它只更新一个全局变量到 temp.py 的作用域。

但问题是,在我们使用import temp.py; print(temp.var)语句之前。
python 在哪里存储了这个 temp.var 的值?
我怎样才能访问它?
如果我想让导入的 str_to_global_var 函数为 script.py 更新全局变量,是否有修改其属性的技巧,以便 python 将其识别为 [=30= 的函数]?

当您的代码被执行时

def str_to_global_var(string, obj):
    command_1 = 'global %s; %s=%r' % (string, string, obj)
    exec(command_1)

通过调用

str_to_global_var('x', 6)

全局变量在模块 temp 中创建。您可以使用下面的

来确认
print ('x' in str_to_global_var.__globals__)
print (str_to_global_var.__globals__['x'])

输出将是

True
6

默认情况下,您不能从另一个模块修改当前模块的上下文。所以如果你有下面的代码

x = 10
str_to_global_var('x', 6)
print ("x = " + str(x))

输出将是

x = 10

如果你想修改当前模块上下文中的变量,那么你需要将该上下文也传递给函数

def str_to_global_var2(globalsvar, string, obj):
    command_1 = 'globalsvar["%s"] = %r' % (string, obj)
    exec(command_1)

然后像下面这样调用它

x = 10
str_to_global_var2(globals(), 'x', 6)
print ("x = " + str(x))

输出将是

x = 6

函数可以简化为

def str_to_global_var3(globalsvar, string, obj):
    globalsvar[string] = obj

这里有一个 str_to_global 的例子,它在调用模块上使用 sys._getframe:

#a.py
def str_to_global(name, value):
    sys._getframe(1).f_globals[name] = value

#b.py
from a import str_to_global
str_to_global('cheese', 'cake')
print(cheese)

cake