python跨文件传输变量
问题描述
我有一个主文件,叫做main.py,在其中需要调用sub.py文件中的一个叫做process的函数,此时由于一些原因,这个process函数需要使用到main.py中定义的一个会随时在main.py中会被修改的变量值t,正常来说,我只需要修改process函数,向其传一个变量t即可完成,但此时由于process在其他文件中被多次调用,不方便对process的传入参数进行增删的修改。那么问题就出现了:
即此时如果直接在sub.py文件中使用from main import x
会导致python报循环导入错误,这是因为在main.py中包含了from sub import process
这一语句
# main.py
from sub import process
t=-1
process()
# sub.py
from main import t
def process():
print("This is process function")
实际上,在运行上述main.py的时候就会报错ImportError: cannot import name 'process' from 'sub'
,这是由于python这个语言的特性导致的,让我们来看看运行main.py的时候究竟发生了什么
在运行main.py文件的时候,首先运行的是from sub import process
,此时,程序会跳转到sub,py文件,并且sub.py第一行开始运行,而此时sub.py第一行恰恰又是from main import t
,于是,程序又跳转到了main.py开始从头运行,就这样程序形成了一个死循环。
解决方案
其实有一种比较简单的解决方法,那就是通过将需要传输的变量保存到外部文件中,如txt或者csv文件,然后再在sub.py
文件中读取文件,将其中的变量提取出来,但考虑到这样的方法需要频繁打开关闭文件,会对程序性能造成较大影响,在这里给出另一种解决方法。
基于全局变量的共享方案
首先创建一个用于共享文件的py文件share.py
,内容如下
x=-1
# 初始化全局变量
def init():
global x
x=0
def get():
global x
return x
def change(value):
global x
x=value
在这个文件中,x用来保存我们需要进行共享的变量,当然这个变量x也可以是字典,其可拓展性更强,如下
x_dict={}
# 初始化全局变量
def init(init_dict):
global x_dict
x_dict=init_dict
def get():
global x_dict
return x_dict
def change(key,value):
global x_dict
x_dict[key]=value
其中,init()
函数用来对共享变量进行初始化,可以通过在main.py
中导入init()
以及change()
函数来修改share.py
中的x_dict
,再通过在sub.py
中导入get()
函数来获取经过修改后的x_dict
在main.py
中测试如下
from sub import process
from share import init,change,get
k='t'
v=-1
my_dict={k:v}
init(my_dict) #init share_dict
res_dict=get() #get share_dict
print(res_dict[k]) #res=-1
change(k,2) #change share_dict
res_dict=get()
print(res_dict[k]) #res=2
process() #This is process function, res = 2
change(k,4)
process() #This is process function, res = 4
在sub.py
中使用方法如下
from share import get
def process():
res_dict=get()
print("This is process function, res =",res_dict['t'])
这样子就实现了python中跨文件变量共享,同时避免了循环导入的问题,该方法的思想与将变量存入外部文件然后再在需要使用的地方读取变量是一致的,但相较起写入\读取外部文件的方法,这个方法会在程序运行起来的时候将这个全局变量x_dict
驻留在内存中,从而避免了频繁读取外部文件的问题
存在的问题
这个方法无法保证多个文件同时读取和写入时变量的一致,这需要通过加锁来解决(未完待续)