我目前有一个全局字典变量
_vars ={
"key_1":"system environmental variable_1",
"key_2":"system environmental variable_2",
................
#around eight key pairs
}
程序运行时调用 initalize_vars 函数会初始化字典_vars
def initialize_vars():
var key in _vars:
_vars[key] = os.path.expandvars(vars[key])
但是,在主函数中,根据用户提供的参数数量,会调用不同的函数,其中一些函数不需要初始化_vars(会引发异常,因为系统环境变量不存在)
例如:
def A():
initialize_vars()
#do something
return something
def B():
#do something
return something
def C():
initialize_vars()
#do something
def main():
如果 sys.argv[1]=="A":
A()
elif sys.argv[1] ==“B”:
乙()
elif sys.argv[1] ==“C”:
C()
所以我的问题是:确保initialize_vars()在已经初始化的情况下不会被多次调用的最佳方法是什么
最佳答案
我认为你可以添加一个全局变量来存储字典的初始化状态,当调用方法initialize_vars时,你可以通过检查这个全局变量的值来决定是否需要初始化.
示例代码如下
vars_initialized = False
def initialize_vars():
global vars_initialized
if False == vars_initialized:
var key in _vars:
_vars[key] = os.path.expandvars(vars[key])
vars_initialized = True
注意:但是在读取/更新此全局变量的值时请注意锁和线程安全,可能会发生以下情况:
- 代码执行 运行到initialize_vars方法并尝试初始化var并正在处理。
- 代码执行B遇到initialize_vars方法,得到vars_initialized的值为False,也尝试初始化它。
- 代码执行A完成初始化并将vars_initialized设置为True。
- 代码执行 B 完成初始化并将 vars_initialized 也设置为 True。
所以可以看到,上面的代码执行过程并不正确,正确的应该是
- 代码执行 运行到initialize_vars方法并尝试初始化var并正在处理。
- 代码执行B遇到initialize_vars方法,发现此时它已经被初始化,所以它在那里等待,直到该过程结束。
- 代码执行A完成初始化并将vars_initialized设置为True。
- 代码执行 B 获得 vars_initialized 为 True 的状态并继续执行。
这里是代码的另一个版本,可能会更好:
vars_initialized = False
vars_initialing = False
def initialize_vars():
global vars_initialized, vars_initialing
vars_initialing = True
if False == vars_initialized:
var key in _vars:
_vars[key] = os.path.expandvars(vars[key])
vars_initialized = True
vars_initialing = False
def A():
if not vars_initialing:
initialize_vars()
else:
while vars_initialing:
//Wait for the init to be finished
sleep(0.1)
#do something
return something
def B():
#do something
return something
def C():
if not vars_initialing:
initialize_vars()
else:
while vars_initialing:
//Wait for the init to be finished
sleep(0.1)
#do something
return something
def main():
if sys.argv[1]=="A":
A()
elif sys.argv[1] =="B":
B()
elif sys.argv[1] =="C":
C()
我熟悉Java,我们在这种情况下使用对象锁(同步),我认为Python需要一些相等的东西来确保这里不会发生冲突,我上面发布的只是这个锁的模拟。
这里可能会用到一种叫做线程锁的东西,这里有一些引用。
关于python - 重构重复的全局字典初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22548863/