错误原理实例如下:
class One(): list = [1, 2, 3] @classmethod def get_copy_list(cls): # copy一份list,这样对list的改变不会影响到此对象的list return cls.list[:] @classmethod def get_list(cls): # 直接返回此对象的list,任何对list的操作都会影响到此对象的list return cls.list if __name__ == '__main__': # 不影响到One对象的list值 a = One.get_copy_list() print(a) # [1, 2, 3] a.append(4) print(a) # [1, 2, 3, 4] print(One.get_list()) # [1, 2, 3] # 影响到One对象的list值 b = One.get_list() print(b) # [1, 2, 3] b.append(5) print(b) # [1, 2, 3, 5] print(One.get_list()) # [1, 2, 3, 5]
解决方法:调用One.get_copy_list()
在flask中,知识点:一个请求 在进入到进程后,会从进程 App中生成一个新的app(在线程中的应用上下文,改变其值会改变进程中App的相关值,也就是进程App的指针引用,包括g,),以及生成一个新的请求上下文(包括session,request)。并把此次请求需要的应用上下文和请求上下文通过dict格式传入到 栈中(从而保证每个请求不会混乱)。并且在请求结束后,pop此次的相关上下文。
错误接口代码大致如下:
class
Model_table
(_ModelPub, DB.Model):
__tablename__ = 'recruit_info'
__keys_map__ = {
'info': [
'uid', 'back_img', 'user_name', 'gender', 'age'
]
@Recruit.route('/update_info/<string:action>', methods=['POST']) info_list = Model_table.__keys_map__['info'] info_list += ['img_id', 'prience_id'] print(info_list)
响应如下(每次请求,都会向model类的列表属性值添加元素,这样会随着时间的增长导致内存消耗越来越大,最终导致服务崩溃):
解决方法:
@Recruit.route('/update_info/<string:action>', methods=['POST']) info_list = Model_table.__keys_map__['info'][:] #copy一份list即可 info_list += ['img_id', 'prience_id'] print(info_list)
效果显示(每个请求不会混乱):
总结:刚开始以为 在一次请求过程中,无论怎么操作都不会影响到其他请求的执行,当时只考虑了在 请求上下文中不会出现这种问题,但是 应用上下文,是 进程App相关属性或常量的一个引用(相当于指针),任何对应用上下文中的改变(g会在每次请求到来时从新赋值,然后在请求结束后跟随应用上下文,请求上下文一起消失),都会影响到其他请求的执行。
相关连接:
https://blog.tonyseek.com/post/the-context-mechanism-of-flask/