我今天正在研究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的函数?
答案 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