上下文管理器可以 返回一个对象,该对象将分配给命名的标识符as
。而且,由__enter__
分配的方法返回的对象as
不一定是上下文管理器本身。
as <identifier>
在创建 新 对象时(如open()
调用一样)使用帮助,但并非仅为上下文创建所有上下文管理器。例如,它们可以重用并且已经创建。
建立 数据库连接 。您只需创建一次数据库连接,但是许多数据库适配器使您可以将该连接用作上下文管理器。输入上下文并开始事务,然后退出并提交事务(成功)或回滚(发生异常时):
with db_connection:
# do something to the database
此处无需创建新对象,使用可以输入上下文,db_connection.__enter__()
然后使用可以再次退出上下文db_connection.__exit__()
,但是我们已经有了 对连接对象的引用。
现在, 可能 是输入时连接对象产生了一个游标对象。现在,可以使用本地名称分配该光标对象了:
with db_connection as cursor:
# use cursor to make changes to the database
db_connection
在这里仍然没有被调用,它已经存在过,我们已经对其进行了引用。但是,db_connection.__enter__()
现在将所产生的任何东西分配给他们,cursor
然后就可以使用了。
文件对象就是这种情况。open()
返回文件对象,然后fileobject.__enter__()
返回文件对象 本身 ,因此您可以open()
在with
语句中使用调用, 并 在一个步骤(而不是两个步骤)中为新创建的对象分配引用。没有这个小把戏,您将不得不使用:
f = open('myfile.txt')
with f:
# use `f` in the block
将所有这些都应用于您的着色器示例;您已经有参考self.shader
。很可能再次self.shader.__enter__()
返回对的引用self.shader
,但是由于您已经有了一个可以正常使用的引用,为什么要为此创建一个新的本地?