当前位置: 首页 > 面试题库 >

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

云胤
2023-03-14
问题内容

我熟悉使用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.__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,但是由于您已经有了一个可以正常使用的引用,为什么要为此创建一个新的本地?



 类似资料:
  • 问题内容: 众所周知,C#提供了一个AS关键字,该关键字会自动执行一次检查,检查对象是否属于某种类型,如果是,则将其强制转换为所需的类型,否则给出null。 在上面的示例中,这里的Object obj可以是User类型或其他类型。用户将获得User类型的对象或null。这是因为C#的As关键字首先执行检查,然后在可能的情况下将对象强制转换为结果类型。 那么Java中有没有与C#的AS关键字等效的关

  • 问题内容: Swift中“ with”关键字的目的是什么?到目前为止,我发现如果需要覆盖现有的全局函数(例如toDebugString),则可以使用关键字。 问题答案: 是 不是 一个关键字-它只是一个外部的参数标识。这也可以: 由于已经定义了函数,因此通过使用外部参数,您将创建 重载 :相同的函数名称,但参数不同。在这种情况下,参数是相同的,但是用一个外部名称标识,并且迅速使它成为具有不同签名的

  • 问题内容: 您好,我试图弄清楚为什么在MSSQL中将兼容模式从80切换为100会破坏下面的功能? 这是我的功能: 问题答案: 尝试在with前面加一个半冒号: 给这篇文章读明白,为什么你需要做到这一点。尖刺: 但是,如果CTE不是批处理中的第一条语句,则必须在WITH关键字之前加上分号。作为一种最佳实践,我宁愿在所有CTE前面加上分号,以使这种一致的方法比记住我是否需要分号更容易。 就个人而言,我

  • 问题内容: 似乎与 使用open .. as代替f =有什么好处?只是语法糖吗?仅保存一行代码? 问题答案: 为了与语句版本等效,您编写的代码应如下所示: 虽然这看起来像语法糖,但可以确保您释放资源。通常,这个世界比这些人为的例子要复杂得多,如果您忘记了一个案例或无法处理一个极端案例,那么您将面临资源泄漏。 该语句使您免于那些泄漏,使编写干净的代码更加容易。有关完整的说明,请参阅PEP 343 ,

  • 问题内容: 我正在尝试从parse.com实现一些代码,并且在void后发现一个关键字。 我难住了,这是什么?您在第二行看到 该文档没有对此进行说明。我知道关键字用于循环。 有人确认吗? 问题答案: 在命名函数中,我们声明参数并在声明行中返回类型。 在匿名函数中,没有声明行-它是匿名的!因此,我们在正文的开头使用一行来代替。 (这是匿名函数的 完整 形式。但是Swift拥有一系列规则,允许在某些情

  • 问题内容: 这个问题已经在这里有了答案 : 如何在LIMIT子句中应用bindValue方法? (10个答案) 5年前关闭。 使用PDO(我正在使用具有Apache 2.2.21,PHP最高为5.3.6和MySQL 5.5.9的MAMP 2.0.5)准备的语句,如果我使用 有用。 我在MySQL的错误中看到这是先前版本中的错误,但我不知道是否仍要解决。 如果仍然存在问题,是否可以通过另一种方式选择