python - 如何在两个单独的脚本中导入共享变量?
问题描述
我有以下简化的python代码:
myproject
├── main.py
├── shared_var.py
└── utils.py
shared_var.py:
FOO = 'INIT'
实用程序.py
import time
from shared_var import FOO
def func_b():
global FOO
print('func_b initial FOO value: ', FOO)
for i in range(10):
FOO = str(i)
print('func_b FOO value: ', FOO)
time.sleep(1)
FOO = 'DONE'
print('func_b FOO value: ', FOO)
主要.py:
import time
from shared_var import FOO
from utils import func_b
import threading
def check_FOO_status():
print('main current FOO: ', FOO)
if FOO == 'DONE':
return True
else:
return False
if __name__ == "__main__":
print('main start FOO value: ', FOO)
t = threading.Thread(target=func_b)
t.start()
running = True
while running:
if check_FOO_status():
break
time.sleep(3)
print('main end FOO value: ', FOO)
这是我试图在我的应用程序中解决的问题的过度简化版本。基本上我想做的是:
- 在 main.py 中启动一个子线程,子线程会异步执行一个耗时的任务。
- 子线程更新全局变量
FOO
以在处理任务时跟踪进度。 - main 并没有被耗时任务阻塞,它产生一个子线程来完成这个任务后,它会继续完成一些其他任务。然后它不断检查全局变量
FOO
以查看子线程的进度。
但是,输出如下:
/usr/local/bin/python3.6 /Users/john/myproject/main.py
main start FOO value: INIT
func_b initial FOO value: INIT
func_b FOO value: 0
main current FOO: INIT
func_b FOO value: 1
func_b FOO value: 2
main current FOO: INIT
func_b FOO value: 3
func_b FOO value: 4
func_b FOO value: 5
main current FOO: INIT
func_b FOO value: 6
func_b FOO value: 7
func_b FOO value: 8
main current FOO: INIT
func_b FOO value: 9
func_b FOO value: DONE
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
main current FOO: INIT
...(infinite loop)
如您所见,显然全局变量有两个副本FOO
。主线程和子线程不共享单个全局变量。我认为这是导入的问题,但在网上搜索后我找不到原因。
有什么建议么?
解决方案
而不是from shared_var import FOO
只写 write import shared_var
,并且在更改/读取此 FOO 变量时使用shared_var.FOO
而不是 just FOO
。在这种情况下,我们使用的事实是,如果某个模块之前已经导入,然后我们尝试再次导入它,python 不会再次导入它,但它只会为您提供对内存中已经存在的对象的引用。看起来这不适用于import from
建筑,所以你需要使用import
.
这是工作代码:
主文件
import time
import shared_var
from utils import func_b
import threading
def check_FOO_status():
print('main current FOO: ', shared_var.FOO)
if shared_var.FOO == 'DONE':
return True
else:
return False
if __name__ == "__main__":
print('main start FOO value: ', shared_var.FOO)
t = threading.Thread(target=func_b)
t.start()
running = True
while running:
if check_FOO_status():
break
time.sleep(3)
print('main end FOO value: ', shared_var.FOO)
实用程序.py
import time
import shared_var
def func_b():
print('func_b initial FOO value: ', shared_var.FOO)
for i in range(10):
shared_var.FOO = str(i)
print('func_b FOO value: ', shared_var.FOO)
time.sleep(1)
shared_var.FOO = 'DONE'
print('func_b FOO value: ', shared_var.FOO)
及其输出:
main start FOO value: INIT
func_b initial FOO value: INIT
main current FOO: INIT
func_b FOO value: 0
func_b FOO value: 1
func_b FOO value: 2
main current FOO: 2
func_b FOO value: 3
func_b FOO value: 4
func_b FOO value: 5
func_b FOO value: 6
main current FOO: 6
func_b FOO value: 7
func_b FOO value: 8
func_b FOO value: 9
main current FOO: 9
func_b FOO value: DONE
main current FOO: DONE
main end FOO value: DONE
推荐阅读
- reactjs - 如何在 React (TypeScript) 中使用依赖注入组件
- ios - 使用 Firebase 使用图像填充 UICollectionView 时如何组织数据
- css - 全屏和音量按钮隐藏在顶部栏后面,在 Swift 的 youtubehelper 中
- perl - 在 GetOptions 中插入和使用未知选项
- c++ - 为 android 和 iOS 构建 OpenSSL CURL
- python - Python Tkinter OOP 继承
- javascript - 如何使与其他对象的表面相交的可见边缘?(THREE.js)
- docker - 容器初始化后,docker 映像中的文件复制到命名卷的速度有多快
- spring-boot - RabbitMQ Spring Boot AMQP - 使用并发线程
- wpf - WPF 日历控件不通过 InputBindings (MVVM) 监听 Enter 键