Python 上下文管理器是否仅用于引发异常?

Python 上下文管理器是否仅用于引发异常?,python,python-3.x,Python,Python 3.x,在python中使用上下文管理器只是为了验证某些数据和处理异常以使代码更干净,这是好的做法还是坏的做法 这就是我的意思: @contextmanager def validate_data(a, b): if a != b: raise ValidationError("Wrong values") if a ==- 1: raise ValidationError("You can't use -1") if a ==- 2: raise Validatio

在python中使用上下文管理器只是为了验证某些数据和处理异常以使代码更干净,这是好的做法还是坏的做法

这就是我的意思:

@contextmanager
def validate_data(a, b):
  if a != b:
    raise ValidationError("Wrong values")
  if a ==- 1:
    raise ValidationError("You can't use -1")
  if a ==- 2:
    raise ValidationError("You can't use -2")
  # etc validations
  yield

if __name__ == '__main__':
  a = 1
  b = 2
  with validate_data(a, b):
    print(a + b)
问题在于我在Python中发现的关于上下文管理器的几乎所有信息都是关于处理连接或读取文件操作的

我可以使用上下文管理器来完成像这样的简单操作吗


对我来说,这看起来像是一个分离责任的好例子,验证与函数体分离,您可以专注于函数做什么,而不是读取所有这些验证行。

在这种情况下,函数只返回
True
(对于有效数据)或
False
(对于无效数据)而
if
语句会更清晰

def is_valid_data(a, b):
    if a != b:
        return False
    ...
    return True

if is_valid_data(a, b):
    print(a + b)
上下文管理器主要用于确保在
with
语句的主体之后运行某些内容,无论该主体执行期间是否引发任何异常。它的目的是作为一个更简单的替代模式,如

# 1) Initialize some stuff
try:
    # 2) Do something with the stuff
finally:
    # 3) Do stuff whether or not the above
上下文管理器封装了步骤1和3:

with context_manager as cm:
    # Do something

with
语句确保在主体之前运行
cm.\uuuuuuuuuuuuuuuuuuuuuuuuuuu
,并确保在主体之后运行
cm.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu退出
语句,即使异常会阻止整个
with
语句主体(或其后的任何内容)从运行。

我看不出在所示的情况下使用上下文管理器而不仅仅是使用普通函数的意义。@jwodder true,我已经修复了屈服。这是一个非常简单的例子。让我们假设我有一个普通函数,它可以有10个可以引发任何异常的
if
条件-因此我想将这10个if移动到上下文管理器。只是为了让函数代码更干净。为什么不让
validate_data
成为一个正常函数,然后执行
b=2;验证_数据(a、b);打印(a+b)
?我看不出所有额外的东西都给了你任何东西。@JETM因为我想使用它的通常工作流-在django视图中,我想显式地提出一个错误,我不能用通常的函数做什么。有点困惑,为什么正常的函数不能显式地提出错误@当我想在不同的条件下提出不同的错误时,这并不能解决问题。然后再提出它们。
with
语句所做的唯一一件事就是捕获第一个异常并将其传递给上下文管理器的
\uuuuuuuuuu
方法,该方法可能会重新引发,也可能不会重新引发。它本身不处理异常。正如我所说的,我希望在django视图中使用它,使用自定义http响应代码引发错误-并且在视图之外的其他位置引发这些错误没有任何效果,因此contextmanager有助于保持视图干净(在某些极少数情况下)。我知道上下文管理器是如何工作的,现在已经阅读了所有关于它们的可用文档。但仍然没有';我不知道我的方法有什么问题。如果可能,为什么不使用它?不久前,协同工作还被称为发电机的副作用。