编程语言
首页 > 编程语言> > python – 没有“as”关键字的“with”语句的含义

python – 没有“as”关键字的“with”语句的含义

作者:互联网

我熟悉使用python的with语句作为在抛出异常时确保对象完成的一种方法.这通常看起来像

with file.open('myfile.txt') as f:
    do stuff...

这是短手的

f = file.open('myfile.txt'):
try:
    do stuff...
finally:
    f.close()

或者班级可能提出的任何其他终结程序.

我最近遇到了一段处理OpenGL的代码:

with self.shader:
    (Many OpenGL commands)

请注意,缺少任何as关键字.这是否表明仍然要调用该类的__enter __和__exit__方法,但该对象永远不会在块中显式使用(即,它通过全局或隐式引用工作)?还是有一些其他意义在逃避我?

解决方法:

上下文管理器可以选择返回一个对象,该对象将被分配给由as命名的标识符.它是由__enter__方法返回的对象,由as分配,不一定是上下文管理器本身.

使用as< identifier>在创建新对象时有帮助,比如open()调用,但并非所有上下文管理器都是为上下文创建的.例如,它们可以重复使用并且已经创建.

进行数据库连接.您只创建一次数据库连接,但许多数据库适配器允许您将连接用作上下文管理器;进入上下文并启动一个事务,退出它并且事务被提交(成功)或回滚(当有异常时):

with db_connection:
    # do something to the database

这里不需要创建新对象,使用db_connection输入上下文.__输入__()并使用db_connection .__ exit __()再次退出,但我们已经有了对连接对象的引用.

现在,输入时可能是连接对象生成了一个游标对象.现在,将该游标对象分配为本地名称是有意义的:

with db_connection as cursor:
    # use cursor to make changes to the database

这里没有调用db_connection,它之前已经存在过,我们已经有了它的引用.但无论db_connection .__输入生成的__()现在都分配给了游标,可以从那里开始使用.

这是文件对象发生的事情; open()返回一个文件对象,fileobject .__ enter __()返回文件对象本身,因此你可以在with语句中使用open()调用,并在一步中而不是两步中分配对新创建的对象的引用.没有这个小技巧,你必须使用:

f = open('myfile.txt')
with f:
    # use `f` in the block

将所有这些应用于着色器示例;你已经有了self.shader的引用. self.shader .__输入__()很可能会再次返回对self.shader的引用,但由于你已经有了一个完全可用的引用,为什么要为它创建一个新的本地?

标签:contextmanager,with-statement,python
来源: https://codeday.me/bug/20190928/1827369.html