微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 `with` 语句中启动多个上下文管理器时使用 `and` 而不是 `,`

如何解决在 `with` 语句中启动多个上下文管理器时使用 `and` 而不是 `,`

在编写单元测试时,我经常使用以下模式:

with self.subTest("Invalid input") and self.assertRaises(ValueError):
  ...

但直到今天我才知道according to python specs,I should be using ,

with self.subTest("Invalid input"),self.assertRaises(ValueError):
  ...

并且规范中没有提到 and 作为一个选项。然而,这些测试似乎总是运行良好。

在这里使用 and 时可能会出现哪些问题?为什么它似乎通常与 , 的工作方式相同?

相关:Multiple variables in a 'with' statement?

解决方法

您拥有的是带有 and 运算符的表达式。如果 and 运算符为 falsey,则返回其第一个操作数,否则返回其第二个操作数。假设 self.subTest(...) 返回一些真实,您的代码等价于:

ctx = self.subTest("Invalid input") and self.assertRaises(ValueError)
with ctx: ...

相当于:

self.subTest("Invalid input")
ctx = self.assertRaises(ValueError)
with ctx: ...

或者:

self.subTest("Invalid input")
with self.assertRaises(ValueError): ...

因此,充其量,您所拥有的内容可能会产生误导。最坏的情况是它是一个错误,因为没有使用 subTest 的上下文管理器。

如果 self.subTest 返回 falsey 值,则永远不会执行 self.assertRaises(...),这将是您测试中的明显错误。

,

加上@deceze 的出色回答,您可以很容易地观察到这一点:您只需要创建自己的上下文管理器。

运行以下代码:

class C:
    def __init__(self,id):
        self.id = id
    def __enter__(self):
        print(f'Entering {self.id}')
        return self
    def __exit__(self,exc_type,exc_value,traceback):
        print(f'Exiting {self.id}')
        return self

with C(0),C(1): print('with statement 1')
print()
with C(2) and C(3): print('with statement 2')

您会看到打印了以下输出:

Entering 0
Entering 1
with statement 1
Exiting 1
Exiting 0

Entering 3
with statement 2
Exiting 3

发生的情况是,对于第一个 with 语句,两个值按顺序输入,然后以相反的顺序退出(这些是 Python 的 with 语句的语义)。但是在第二个 with 中,只有第二个项目被处理(进入然后退出) - 因为第一个被 and 运算符丢弃。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?