Python的'with'语句与'with .. as

20 投票
4 回答
11758 浏览
提问于 2025-04-15 11:48

我刚刚因为一个差异而抓狂,想知道在Python 2.5中,这个差异到底是什么。

我有两段代码(dbao.getConnection() 返回一个MySQLdb连接)。

conn = dbao.getConnection()
with conn:
    # Do stuff

还有

with dbao.getConnection() as conn:
    # Do stuff

我以为这两段代码的效果是一样的,但显然不是,因为后面那段的conn对象变成了一个Cursor。这个光标是从哪里来的?有没有办法把变量初始化和with语句结合起来呢?

4 个回答

1

“with”语句的作用是确保某些操作能够正确开始和结束,比如说数据库事务。

在Python中处理数据库连接时,通常的做法是在“with”语句开始时创建一个游标,然后在结束时提交(保存)或者回滚(撤销)这个事务。

你给出的两个代码块从“with”语句的角度来看是一样的。你也可以在第一个代码块中加上“as”,这样就能得到游标。

你需要查看你使用的对象是如何支持“with”语句的。

更多信息可以参考这个链接:http://docs.python.org/whatsnew/2.5.html#pep-343-the-with-statement

38

乍一看,这可能有点让人困惑,但是

with babby() as b:
    ...

并不等同于

b = babby()
with b:
    ...

要理解为什么这样,我们来看一下上下文管理器是怎么实现的:

class babby(object):
    def __enter__(self):
        return 'frigth'

    def __exit__(self, type, value, tb):
        pass

在第一种情况下,名字 b 会绑定到上下文管理器的 __enter__ 方法返回的内容。这个返回的内容通常是上下文管理器本身(比如文件对象),但不一定是;在这个例子中,它是字符串 'frigth',而在你的例子中,它是数据库的游标。

在第二种情况下,b 就是上下文管理器对象本身。

21

简单来说,with 语句中的 as 部分所赋的值,就是上下文管理器的 __enter__ 方法返回的内容。

撰写回答