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

Posted

技术标签:

【中文标题】如何在两个单独的脚本中导入共享变量?【英文标题】:How to import a shared variable in two separate scripts? 【发布时间】:2021-03-29 17:23:47 【问题描述】:

我有以下简化的 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 有两个副本。主线程和子线程不共享单个全局变量。我认为这是导入的问题,但在网上搜索后我找不到原因。

有什么建议吗?

【问题讨论】:

【参考方案1】:

不写from shared_var import FOO,只写import shared_var,当改变/读取这个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

【讨论】:

以上是关于如何在两个单独的脚本中导入共享变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Perl 脚本之间共享 ENV 变量

VueJS 和 SASS - 在脚本中导入和使用 SASS 变量

PyQt4 跨 .py 文件共享 QLineEdit 变量

如何在Powershell中的脚本之间共享变量?

我应该以啥顺序在我的共享模块中导入模块

如何在线程之间共享变量?