Python “with”表示其中一个变量可能为None

Python “with”表示其中一个变量可能为None,python,python-3.x,Python,Python 3.x,我有一个需要1或2个资源的功能: def my_function(): res1 = None if some_cond: res1 = get_resouce1() res2 = get_resouce2() return res2, res1 当我这样做时,如果某个条件为False,我会得到一个异常: a2, a1 = my_function() with a2, a1: # doing something..... # "a1" m

我有一个需要1或2个资源的功能:

def my_function():
  res1 = None
  if some_cond:
    res1 = get_resouce1()

  res2 = get_resouce2()
  return res2, res1
当我这样做时,如果某个条件为False,我会得到一个异常:

  a2, a1 = my_function() 
  with a2, a1:
    # doing something.....


    # "a1" might be None here
    # thus the exception `AttributeError: __exit__` 
    # might be thrown when `a1` is None.

  print("helllllloooo")
如何解决这个问题?

不要返回None,使用Null对象模式并返回虚拟上下文管理器。它可以很快完成与装饰

import contextlib
@contextlib.contextmanager
def null_ctx_mgr():  # context manager that does nothing on enter and exit
    yield

def get_ctx_mgrs():
    # your function - returns context managers, never returns None
    return null_ctx_mgr(), null_ctx_mgr()

# actual usage
c1, c2 = get_ctx_mgrs()
with c1, c2:
    print(1)

这里对Python来说很陌生,但是为什么不将res2、res1返回值存储在元组中,然后使用for循环遍历它呢

比如:

foo = my_function()

for element in foo:
    doSomething(element)
然后可以检查值是否为None

抱歉,如果这不是正确的方法,也尝试学习…:

编辑:


当然,我想如果每个元素不是错误消息中提到的None,那么您可以在每个元素上使用with;我猜a1的值是None,因为with无法调用uuuu enter和uuu exitfunctions@MoinuddinQuadri,您猜对了。通过返回空的上下文管理器而不是无?您是否希望得到一个不费吹灰之力就能复制粘贴的答案?堆栈溢出不是这样工作的。在您的情况下,它返回收益率。如何将其应用到我的代码中?我很想知道为什么答案被否决,以及如何改进它。@Saurabh这可以通过使用c1=null\u ctx\u mgr而不是c1=None应用到您的代码中;我认为,根据您提供的用例,您接受的答案并不能真正起作用。@Moinuddin Quadi:我理解我的解决方案是错误的,我很惊讶看到我的建议被OP.接受。。。但是,有谁能告诉我,我的noob方法有什么问题,而不是直接投反对票?提前谢谢