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
我今天正在研究 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