如何在两个单独的脚本中导入共享变量?
How to import a shared variable in two separate scripts?
我有以下简化的 python 代码:
myproject
├── main.py
├── shared_var.py
└── utils.py
shared_var.py:
FOO = 'INIT'
utils.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)
main.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
,只写import shared_var
,当changing/reading这个FOO变量使用shared_var.FOO
而不是FOO
。在这种情况下,我们使用的事实是,如果某个模块之前已经导入,然后我们尝试再次导入它,python 不会再次导入它,但它只会给你引用已经存在的对象记忆。看起来这不适用于 import from
构造,因此您需要使用 import
.
这是工作代码:
main.py
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)
utils.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
我有以下简化的 python 代码:
myproject
├── main.py
├── shared_var.py
└── utils.py
shared_var.py:
FOO = 'INIT'
utils.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)
main.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
,只写import shared_var
,当changing/reading这个FOO变量使用shared_var.FOO
而不是FOO
。在这种情况下,我们使用的事实是,如果某个模块之前已经导入,然后我们尝试再次导入它,python 不会再次导入它,但它只会给你引用已经存在的对象记忆。看起来这不适用于 import from
构造,因此您需要使用 import
.
这是工作代码:
main.py
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)
utils.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