UnboundLocalError:分配前引用的局部变量“光标”
Posted
技术标签:
【中文标题】UnboundLocalError:分配前引用的局部变量“光标”【英文标题】:UnboundLocalError: local variable 'cursor' referenced before assignment 【发布时间】:2015-12-06 06:05:26 【问题描述】:所以我是一个新手,但正在使用flask/mysql 中的注册系统表单
我收到此错误(UnboundLocalError: local variable 'cursor' referenced before assignment)
在玩了几个小时的代码和研究之后,我需要你的帮助。
这是我的文件,如果还有什么需要分享的,请告诉我。 谢谢
from flask import Flask, render_template, json, request
from flask.ext.mysqldb import MySQL
from werkzeug import generate_password_hash, check_password_hash
app = Flask(__name__)
mysql = MySQL()
app.config['MYSQL_DATABASE_USER'] = 'x'
app.config['MYSQL_DATABASE_PASSWORD'] = 'x'
app.config['MYSQL_DATABASE_DB'] = 'x'
app.config['MYSQL_DATABASE_HOST'] = 'x'
mysql.init_app(app)
@app.route('/')
def main():
return render_template('index.html')
@app.route('/login')
def login():
return render_template('login.html')
@app.route('/showSignUp')
def showSignUp():
return render_template('signup.html')
@app.route('/signUp',methods=['POST','GET'])
def signUp():
try:
_name = request.form['inputName']
_email = request.form['inputEmail']
_password = request.form['inputPassword']
# validate the received values
if _name and _email and _password:
# All Good, let's call the MySQL
conn = mysql.connect()
cursor = conn.cursor()
_hashed_password = generate_password_hash(_password)
cursor.callproc('sp_createUser',(_name,_email,_hashed_password))
data = cursor.fetchall()
if len(data) is 0:
conn.commit()
return json.dumps('message':'User created successfully !')
else:
return json.dumps('error':str(data[0]))
else:
return json.dumps('html':'<span>Enter the required fields</span>')
except Exception as e:
return json.dumps('error':str(e))
finally:
cursor.close()
conn.close()
if __name__ == '__main__':
app.run()
【问题讨论】:
【参考方案1】:您只在 if 块中定义 conn
和 cursor
检查表单值。如果未输入块,则它们未定义,但您仍然尝试引用它们以关闭它们。如果你已经定义了它们,你应该只在两者上调用close
。要么将 conn =
和 cursor =
移到 if 块之前,要么将 close
调用移到块内。
但是,更大的问题是您对如何使用 Flask-MySQLdb 有误解/过于复杂。它会在请求完成时自动创建连接并关闭它,这也会关闭游标。只需使用docs 中所述的扩展名即可。
...
cur = mysql.connection.cursor()
cur.callproc('sp_createUser', (name, email, hashed_password))
data = cur.fetchall()
...
【讨论】:
【参考方案2】:我个人建议使用上下文管理器来处理光标和连接的打开和关闭。您可以相当简单地实现这一点,并且它更干净,更易于调试。这也将消除尝试关闭连接或游标之前在您的巨型 try except 块中打开它的问题。
from contextlib import closing
# do a bunch of stuff prior to opening connection
with closing(mysql.connect()) as conn:
with closing(conn.cursor()) as cursor:
# do a bunch of stuff and don't worry about running .close()
您可以查看closing
here 的文档。
使用closing
会将您的代码更改为类似这样。虽然它可以使用更多的重构,但这是代码审查网站的问题。
from flask import Flask, render_template, json, request
from flask.ext.mysqldb import MySQL
from werkzeug import generate_password_hash, check_password_hash
from contextlib import closing
app = Flask(__name__)
mysql = MySQL()
app.config['MYSQL_DATABASE_USER'] = 'x'
app.config['MYSQL_DATABASE_PASSWORD'] = 'x'
app.config['MYSQL_DATABASE_DB'] = 'x'
app.config['MYSQL_DATABASE_HOST'] = 'x'
mysql.init_app(app)
@app.route('/')
def main():
return render_template('index.html')
@app.route('/login')
def login():
return render_template('login.html')
@app.route('/showSignUp')
def showSignUp():
return render_template('signup.html')
@app.route('/signUp',methods=['POST','GET'])
def signUp():
try:
_name = request.form['inputName']
_email = request.form['inputEmail']
_password = request.form['inputPassword']
# validate the received values
if _name and _email and _password:
# All Good, let's call the MySQL
with closing(mysql.connect()) as conn:
with closing(conn.cursor()) as cursor:
_hashed_password = generate_password_hash(_password)
cursor.callproc('sp_createUser',(_name,_email,_hashed_password))
data = cursor.fetchall()
if len(data) is 0:
conn.commit()
return json.dumps('message':'User created successfully !')
else:
return json.dumps('error':str(data[0]))
else:
return json.dumps('html':'<span>Enter the required fields</span>')
except Exception as e:
return json.dumps('error':str(e))
if __name__ == '__main__':
app.run()
【讨论】:
所以我删除了我的 finally 代码,直到 if name 并将其替换为您的 cmets 之间的代码并导入上下文库? 是的,删除 finally 语句并导入该库并将 opens 更改为 with 语句,您应该会很好。 啊,我明白了。我以前从未使用过烧瓶,但我熟悉纯 python 中的手动数据库连接。 @JasonMartinez,切换到 django。 ;) djangoproject.com喜剧+1 @electrometro 我想了一会儿,但我花了很多时间在视频和研究如何用 Python 和烧瓶做事,我拒绝放弃。最终虽然我可能会。以上是关于UnboundLocalError:分配前引用的局部变量“光标”的主要内容,如果未能解决你的问题,请参考以下文章
UnboundLocalError:分配前引用的局部变量“公会”
分配前引用的 /blog/search/ 局部变量 'cd' 处的 UnboundLocalError
机器人框架:UnboundLocalError:分配前引用的局部变量“cellValue”
Django:UnboundLocalError:分配前引用的局部变量“公司”