1、首先需要先了解python关键字global
了解变量作用域
Python变量的作用域一共有4种,分别是:
- L (Local) 局部作用域
- E (Enclosing) 闭包函数外的函数中
- G (Global) 全局作用域
- B (Built-in) 内建作用域 以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。
示例1:
x = 4
def func_d():
x += 1
print (x)
func_a()
func_b()
func_c()
func_d()
输出(看这里例子我们可以明白,在func_d函数内的局部作用域内,是找不到已经声明的变量x的):
UnboundLocalError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_22876\316391158.py in
21 func_b()
22 func_c()
—> 23 func_d()
~\AppData\Local\Temp\ipykernel_22876\316391158.py in func_d()
14
15 def func_d():
—> 16 x += 1
17 print (x)
18
UnboundLocalError: local variable ‘x’ referenced before assignment
示例2:
x = 5
def func_a():
x = 4
print (x)
def func_b():
print (x)
def func_c():
global x
x += 1
print (x)
4
5
6
详细关于python作用域及关键字global的解析可以参考此链接:https://zhuanlan.zhihu.com/p/111284408
2、已加载神经网络模型为例:
示例3:
import time
model = None
def bulid_model():
print ('model loading ......')
global model
model = 'my model'
time.sleep(10)
def main():
print ('start......')
start = time.time()
global model
if model is None:
bulid_model()
print (model)
end = time.time()
print (f'runtime:{end-start}')
if __name__ == '__main__':
print ('########################time:1.........############################')
main()
print ('########################time:2.........############################')
main()
输出(利用global函数,第一次调用main函数时,需要加载模型,之后模型就会保存在内存中,之后再调用main函数就不要加载模型了):
########################time:1…############################
start…
model loading …
my model
runtime:10.005867719650269
########################time:2…############################
start…
my model
runtime:0.0
3、这里就引出了第三个问题,已经加载的变量(模型),什么时候消失?
Python内部的变量回收机制是基于垃圾回收机制的,它会自动检测不再被使用的对象,并在适当的时候将其从内存中释放掉,以避免内存泄漏。
对于已加载的模型变量,它会一直存在于内存中,直到程序结束或者该变量被显式地删除或重新赋值。这意味着,如果你在一个长时间运行的程序中加载了一个模型,并将其保存到一个全局变量中,那么该模型会一直占用内存直到程序结束或者该全局变量被删除或重新赋值。
在实际应用中,为了避免内存泄漏和提高程序的性能,可以在不再需要使用模型变量时将其显式地删除。例如,在上面的示例代码中,可以在应用程序退出时使用 del 关键字将 model 变量删除,以释放其占用的内存。
那在web接口中,持续被调用,模型会重复被加载吗?
答案肯定是不会的!常用的框架fastapi、flask、Django等,启动接口后,模型就会被加载,保存在内存中,程序一直挂在在后台,再之后的调用中就不会再次加载模型了,除非程序被关闭。