【问题标题】:mysql.connect() returns different type when used in with statementmysql.connect() 在 with 语句中使用时返回不同的类型
【发布时间】:2016-01-26 21:50:16
【问题描述】:

我正在将 Flask 与 Flask-MySQL 一起使用,并且之前正在执行以下操作:

db = mysql.connect()
cursor = db.cursor()
#do database stuff
cursor.close()
db.close()

但我想我会让事情变得更简洁、更惯用,所以我尝试了:

with mysql.connect() as db, db.cursor() as cursor:
    #do database stuff

它给了我以下错误“AttributeError:'Cursor'对象没有属性'cursor'”

经过一番调查,当我自己执行 mysql.connect() 时,它返回了一个连接对象,但是当我在 with 语句中执行此操作时……它返回了一个游标对象!所以这行得通:

with mysql.connect() as cursor:
    #do database stuff

那么这里发生了什么?为什么在 with 语句中返回类型会改变?我查看了Flask-MySQL的源代码,但找不到任何东西......

另外,在 with 块的末尾关闭数据库连接是否仍然可以正常工作?

相关版本信息:

  • Python == 2.7.3
  • 烧瓶 == 0.10.1
  • Flask-MySQL == 1.3

【问题讨论】:

    标签: python mysql flask


    【解决方案1】:

    表达式:

    with X as Y:
        ....
    

    并不意味着Y“是”X。而是调用X.__enter__(),然后将其结果绑定到Y 以作为with 语句的主体。

    with主体的末尾,或者发生异常时,调用X.__exit__(...)来处理成功或失败。

    在这种情况下,mysql.connect() 的结果是一个连接,它公开了一个执行以下操作的上下文管理器:

    • __enter__ 创建一个游标并开始一个事务;
    • __exit__ 酌情提交或回滚事务。

    【讨论】:

    • 但是当我在github.com/cyberdelia/flask-mysql/blob/master/flaskext/mysql.py查看Flask-Mysql的源代码时,类中没有__enter__OR__exit__函数,只有一个__init__函数。
    • @jcmiller 正如我所说,正是mysql.connect()result 公开了上下文管理器API。在这种情况下,结果是 MySQLdb.connect 的返回值(请参阅您链接的代码),这是一个 MySQLdb.Connection ...这是公开 api 的类。
    • 好的,感谢@donkopotamus 帮助我解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2019-06-20
    • 2016-10-26
    • 1970-01-01
    相关资源
    最近更新 更多