【问题标题】:Wrapping a Python function that uses with包装使用 with 的 Python 函数
【发布时间】:2019-06-25 17:20:52
【问题描述】:

假设有一个 python 函数 foo() 使用了一些资源,并且被调用如下:

   with foo(x,y,z) as f:
       doSomething(f)

到目前为止一切顺利。现在让我们说 foo 基于各种因素接受一组复杂的参数,我想定义一个包装函数以使事情变得更简单。比如:

def simple_foo():
    if x:
       return foo(a,b,c)
    else:
       return foo(d,e,f)

现在,我想用 simple_foo 代替 foo,例如:

with simple_foo() as f:
    doSomething(f)

但是,不出所料,这不起作用。如何编写 simple_foo() 来获得这种行为?

【问题讨论】:

  • 它被称为上下文管理器 - 看看例子here
  • “但是,不出所料,这不起作用。”这怎么行不通,究竟
  • @juanpa.arrivillaga 给出:AttributeError: aexit
  • 如果ˋfooˋ 是一个合适的上下文管理器,这确实工作。在 ˋwithˋ 内部而不是在外部构造上下文管理器没有什么神奇之处。 究竟你的问题是什么?
  • @chessprogrammer 什么?请使用minimal reproducible example 编辑您的帖子,包括完整的错误消息

标签: python python-3.x with-statement


【解决方案1】:

contextmanagerdoc)装饰函数foo()

from contextlib import contextmanager

@contextmanager
def foo(a, b, c):
    try:
        yield a + b + c
    finally:
        pass

def simple_foo(x):
    if x:
        return foo(1, 2, 3)
    return foo(4, 5, 6)

with simple_foo(True) as v:
    print(v)

with simple_foo(False) as v:
    print(v)

打印:

6
15

【讨论】:

  • 这只会将问题陈述的ˋfooˋ更改​​为已经是上下文管理器。
  • 我不确定这是否能回答问题。我根本不想修改 foo 。假设 foo 已经定义为上下文管理器,我想换行。
  • @chessprogrammer 我不明白。您无需修改​​ foo,您只需创建新函数 simple_foo() 即可构造新的上下文管理器。
  • @AndrejKesely 不,我是不明白的人 :)
【解决方案2】:

您可以通过编写一个内部调用该函数的自定义上下文管理器来做到这一点,试试下面给出的代码:

class SimpleFoo:

   def __init__(self,x,y,z, option):
       self.x = x
       self.y = y
       self.z = z
       self.option = option


    def __enter__(self):
       if self.option:
          return foo(self.x,self.y,self.z)
       else:
          return foo(self.y,self.z,self.x)

   def __exit__(self, type, value, traceback):

       if type != None:
           print("Error in SimpleFoo")
           print("Error Type :", type)
           print("Error Value :", value)
           print("Error Traceback :", traceback)
           self.status = value

现在如果你想使用它,如下使用它:

with SimpleFoo(1,2,3,True) as foo:
     doSomething(foo)

我希望这会有所帮助。

【讨论】:

  • 您可以使用三个反引号 (```)(esc 下面的键)来正确格式化您的代码,而不是每行使用 4 个空格。你的类没有正确缩进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 2017-12-06
  • 2018-10-12
相关资源
最近更新 更多