使用语句隐藏后期函数调用

时间:2016-06-20 22:17:32

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

我有一个函数f,它返回两个参数。在此功能之后,我使用第一个参数。我需要第二个将事物与另一个函数g粘合在一起。所以我的代码看起来像:

a, b = f()
# do stuff with a
g(b)

这是非常重复的,所以我想我可以使用类似RAII方法的东西。但是,由于我不知道对象什么时候会死,我的主要目标是摆脱重复的代码,我使用了with语句:

with F() as a:
    # do stuff with a

就是这样。我基本上围绕这个函数创建了一个对象F,提供了__enter____exit__函数(显然是__init__函数)。

但是,我仍然想知道这是否是正确的“Pythonic”方法来处理这个问题,因为with语句用于处理异常。特别是这个__exit__函数有三个参数,我目前没有使用它。

编辑(进一步说明): 每当我打电话f()我都需要对b做点什么。两者之间发生了什么并不重要。我把它表达为g(b)。而这正是我隐藏在with声明中。因此,程序员不必在每次调用g(b)后一次又一次地键入f(),这可能会变得非常混乱和混乱,因为#do stuff with a可能会变得冗长。

2 个答案:

答案 0 :(得分:1)

对于其他人阅读您的代码(或者您在6个月内阅读),上下文管理器可能会暗示资源的创建/初始化和关闭/删除,而且我会非常谨慎地重新定义这些成语。 / p>

您可以使用合成,而不是上下文管理器:

def func(a, b):
    # do stuff with a & optionally b

def new_f(do_stuff):
    a, b = f()
    do_stuff(a, b)
    g(b)


new_f(func)

答案 1 :(得分:1)

稍微更加pythonic的方式是使用contextlib模块。您可以通过__enter____exit__函数推出自己的课程。

from contextlib import contextmanager

def g(x):
    print "printing g(..):", x

def f():
    return "CORE", "extra"

@contextmanager
def wrap():
    a, b = f()
    try:
        yield a
    except Exception as e:
        print "Exception occurred", e
    finally:
        g(b)
if __name__ == '__main__':
    with wrap() as x:
        print "printing f(..):", x
        raise Exception()

输出:

$ python temp.py
printing f(..): CORE
Exception occurred
printing g(..): extra