Python类外定义int变量及Flask Resource内计数变量无法累加问题
问题解答
问题本质说明
Python完全支持在类外部定义int类型的全局变量,你遇到的两个报错/异常问题本质都是变量作用域规则和Flask Resource的实例化逻辑导致的:
- 第一个版本报错原因:
在函数/方法内部对变量做赋值操作时,Python默认会将该变量识别为当前作用域的局部变量。myInt +=1等价于myInt = myInt +1,运行时会先尝试读取局部变量myInt的值,但你并没有在post方法内部定义该变量,所以抛出未定义错误。
而你对myList的操作是直接赋值myList = json.loads(recivedJSON),相当于在post方法内部新建了一个和全局变量同名的局部变量,所以不会报错,但此时你修改的只是局部变量,全局的myList并不会被更新。 - 第二个版本计数始终为1的原因:
Flask的Resource类每次收到请求时,都会创建一个全新的实例来处理请求。你用self.myInt操作时,会在当前实例上新建一个实例属性,初始值拷贝自类属性myInt的初始值0,加1后就是1,下次请求又会新建实例,重新从0开始计算,所以每次打印都是1。
修复方案
方案1:正确使用全局变量
如果要在方法内部修改全局变量,需要先通过global关键字声明变量是全局作用域的:
# 导入Flask、json等依赖 from flask import Flask, request from flask_restful import Resource, Api import json app = Flask(__name__) api = Api(app) myList = [] myInt = 0 # 等价于int(),写法更直观 class MyResource(Resource): def post(self): # 声明要修改的是全局变量 global myInt, myList # 接收JSON并解析 receivedJSON = request.get_data() myList = json.loads(receivedJSON) myInt += 1 print(myInt) # 其余逻辑 return {"count": myInt, "data": myList}, 200 api.add_resource(MyResource, '/submit') if __name__ == '__main__': app.run(debug=True)
方案2:直接访问类属性
不想用全局变量的话,不要通过实例self访问类属性,直接通过类名访问即可,所有实例共享同一个类属性:
# 导入依赖同上 myList = [] class MyResource(Resource): myInt = 0 def post(self): global myList receivedJSON = request.get_data() myList = json.loads(receivedJSON) # 直接通过类名修改类属性 MyResource.myInt += 1 print(MyResource.myInt) # 其余逻辑 return {"count": MyResource.myInt, "data": myList}, 200
注意事项
上面两种方案仅适用于单进程部署的场景,如果生产环境用多worker部署Flask服务,多进程之间内存不共享,计数会出现不一致的问题,此时需要用Redis、本地文件、数据库等跨进程的存储介质来保存计数值。
内容的提问来源于stack exchange,提问作者Wuagliono
相关产品推荐
相关产品推荐

