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

时间:2017-11-24 10:44:42

标签: python-3.x scope global-variables python-import

我今天正在研究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()(deepcopy将失败)。它们在删除2个无关标识符“new_global”和“cur_global”之后进行比较,因此在浅拷贝级别说,解释器认为在使用导入的str_to_global_var函数后script.py的全局范围没有任何变化,我们都知道它只会将一个全局变量更新为temp.py的范围。

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

2 个答案:

答案 0 :(得分:7)

以下是使用 sys._getframe 在调用模块上运行的str_to_global示例:

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

答案 1 :(得分:3)

执行代码时

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