如何解决如何在两个模块之间共享一个变量的副本?
我想要一个以全局方式运行的var副本:即,它的存储一次存在,并且两个模块中对它的所有引用都读取和写入相同的存储。我该如何使用总共两个模块来获得这种行为?
这是我的尝试,但失败了:
# module1
#!python
import module2
var = 1
def touch_var():
global var
print(var,id(var))
var = 3
print(var,id(var))
def main():
global var
print(var,id(var))
var = 2
print(var,id(var))
module2.do_func()
print(var,id(var))
touch_var()
print(var,id(var))
if __name__ == '__main__':
main()
# module2
#!python
import module1
def do_func():
print(module1.var,id(module1.var))
module1.touch_var()
print(module1.var,id(module1.var))
module1.var = 4
print(module1.var,id(module1.var))
输出为:
1 17006627360
2 17006627392
1 17006627360
1 17006627360
3 17006627424
3 17006627424
4 17006627456
2 17006627392
2 17006627392
3 17006627424
3 17006627424
我已经尝试过使用可变类型进行赋值:
#!python
import module2
var = [1]
def touch_var():
global var
print(var,id(var))
var = [3]
print(var,id(var))
var = [2]
print(var,id(var))
if __name__ == '__main__':
main()
#!python
import module1
def do_func():
print(module1.var,id(module1.var))
module1.var = [4]
print(module1.var,id(module1.var))
我得到这个结果:
[1] 7696579790600
[2] 7696579792072
[1] 7696579790664
[1] 7696579790664
[3] 7696579790600
[3] 7696579790600
[4] 7696579790664
[2] 7696579792072
[2] 7696579792072
[3] 7696579790600
[3] 7696579790600
而且我尝试分配给可变类型的元素:
#!python
import module2
var = [1]
def touch_var():
global var
print(var,id(var))
var[0] = 3
print(var,id(var))
var[0] = 2
print(var,id(module1.var))
module1.var[0] = 4
print(module1.var,id(module1.var))
我得到这个结果:
[1] 7696579790600
[2] 7696579790600
[1] 7696579790664
[1] 7696579790664
[3] 7696579790664
[3] 7696579790664
[4] 7696579790664
[2] 7696579790600
[2] 7696579790600
[3] 7696579790600
[3] 7696579790600
三个都给出相同的结果。
我想要的输出是这样:
1
2
2
2
3
3
4
4
4
3
3
我为什么要得到我得到的?我如何得到想要的东西?
请注意,这并非@prune所假定的“ Python:在模块和其中的类之间共享全局变量”的重复,因为在那个答案中,问题在于使用“ from module import *”产生了问题,我不是在这里另一个答案是问题来自使用不可变类型,我已经证明这不是问题。另外,我的标准之一是使用两个文件解决此问题,但是这个问题使用三个文件。
解决方法
您的问题出在您有循环进口的事实上。您正在运行module1中的代码以启动。这将创建module1名称空间的一个副本。然后,您要从module1调用module2中的代码,其中module2也会导入module1。在module2中调用import module1
正在创建module1名称空间的第二个副本。
这就是为什么您在module2中的第一个调用会打印1
的原因,因为这是它最初在module1.py
中设置的值,并且您刚刚导入了它。在module2中的所有调用,甚至那些在module1中调用的调用,都在处理module1的第二个副本。
这就是为什么当您退出对模块2的调用并返回到模块1时,变量返回到值2
的原因,即您调用模块2之前的值。调用module2可以始终对module1的第二个副本进行操作,从而不会对module1的原始副本进行任何更改。
这是一种使自己确信这种情况正在发生的方法。制作名为module3.py的module1.py的副本,并在module2.py中包含该副本而不是module1.py。您将获得完全相同的结果,除了现在可以清楚地知道发生了什么,因为您不希望module1中的var
和module3中的变量是相同的变量。
这是一个简单的解决方法:
#!python
# module2
import __main__ as module1
您的示例无法按预期运行的原因是,由于执行的脚本始终以“ __main__”的形式添加到sys.modules
中。因此,以后使用其文件名 导入它时,您将获得对其他模块对象的引用。在这方面,由于重新导入任何其他模块将始终引用sys,modules
中的同一对象,因此对其进行了特殊处理。
(注意:尽管上述修复解决了您的问题,但它是usually considered bad practice)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。