嵌套生成器函数中的yield

时间:2014-06-25 17:08:04

标签: python

我该怎么做才能让它发挥作用?

def my_yield(l):
    try:
        x = open(l[0], 'r')
        y = open(l[1], 'w')
        yield x, y
    finally:
        x.close()
        y.close()




def my_wrapper(list):
    for l in list:
        return my_yield(l)   #<<< what should I put here??


def main():
    list = [('a', 'b'), ('c', 'd')]
    for key, value in my_wrapper(list):
        print key, value
main()

在原始函数中my_wrapper做了一些。

逻辑解决方案是在my_wrapper中产生并在my_yield中返回,但在这种情况下,文件将在到达main中的循环时关闭。

2 个答案:

答案 0 :(得分:0)

您可以在包装器和包装函数中使用yield。所以

def my_yield(l):
    try:
        x = open(l[0], 'r')
        y = open(l[1], 'w')
        yield x, y
    finally:
        x.close()
        y.close()

def my_wrapper(the_list):
    for l in the_list:
        yield my_yield(l)

在许多情况下,这种方法很好用。例如,这里的代码返回列表中的每对相邻项:

def create_list():
    for i in range(5):
        yield i

def pair_list():
    generator = create_list()
    first = next(generator)
    for second in generator:
        yield first, second
        first = second

但是,在yield中使用my_yield会导致一个非常重要的问题 - yield语句会导致代码无法控制my_yield函数,在for循环的下一次迭代中返回或调用next。这意味着只有在没有例外的情况下才会关闭文件。

举例说明:

for x, y in my_yield(('1', '2'))
    raise Exception('BORKED!')

这会导致xy被打开,但永远不会被关闭。

答案 1 :(得分:-1)

我没有看到使用包装器的需要,arond生成器,你可以让生成器产生元组并在循环中使用它。另外,建议不要使用list作为变量名,因为有一个名为list的容器。

def gen(mylist):
    for elem in mylist:
        yield (elem[0], elem[1])

def main():
    mylist = [('a', 'b'), ('c', 'd')]
    for key, value in gen(mylist):
        with open(key, 'r') as keyfile:
            with open(value, 'w') as valuefile:
                #do whatever with keyfile and valuefile

main()