如何在两个单独的脚本中导入共享变量?

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)

这是我试图在我的应用程序中解决的问题的过度简化版本。基本上我想做的是:

  1. 在main.py启动一个子线程,子线程会异步执行一个耗时任务
  2. 子线程更新全局变量 FOO 以在处理任务时跟踪进度。
  3. 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