python-装饰生成器

python-装饰生成器,python,generator,decorator,Python,Generator,Decorator,我有两个不同版本的函数;它读取一个大文件(我在这里简化了它并读取一个非常小的excel文件) Version 1:读取整个文件并返回行列表 Version 2:在生成器的帮助下逐行阅读 我想装饰这两个函数的输出,并根据不同的逻辑在每行末尾添加一些内容,这就是为什么我认为我需要一个不同的定制装饰器。然而,我不知道怎样才能在装饰师的帮助下实现它?特别是当我有收益而不是回报的时候 版本1: @dec def readxls(): fileBook = xlrd.open_workbook('.

我有两个不同版本的函数;它读取一个大文件(我在这里简化了它并读取一个非常小的excel文件)

Version 1:
读取整个文件并返回行列表
Version 2:
在生成器的帮助下逐行阅读

我想装饰这两个函数的输出,并根据不同的逻辑在每行末尾添加一些内容,这就是为什么我认为我需要一个不同的定制装饰器。然而,我不知道怎样才能在装饰师的帮助下实现它?特别是当我有收益而不是回报的时候

版本1:

@dec
def readxls():
    fileBook = xlrd.open_workbook('../decorator.xls')
    sh = fileBook.sheet_by_name("Sheet1")
    out = []
    for row_index in xrange(1, sh.nrows):
        out.append(sh.row_values(row_index))
    return out
第2版:

@dec2
def readxls():
    fileBook = xlrd.open_workbook('../decorator.xls')
    sh = fileBook.sheet_by_name("Sheet1")
    for row_index in xrange(1, sh.nrows):
        yield sh.row_values(row_index)
假设excel文件如下所示:

Col1    Col2    Col3
Val11   Val12   Val13
Val21   Val22   Val23
我希望装饰输出以获得以下结果:

Col1    Col2    Col3   0  Col1Col2
Val11   Val12   Val13  1  Val11Val12
Val21   Val22   Val23  2  Val21Val22

为了得到像这样的输出,我的dec1和dec2函数应该怎么做?

假设decorator对函数的结果进行处理并给出新的结果,所以知道结果是什么是关键,在这种情况下,例如,结果是
[[['val11','val12','val13'],['val21'、'val22'、'val23']
用于版本1,并为第二个版本提供一个包含该版本元素的生成器。有了这些知识,我们可以继续制作装饰器,例如

from functools import wraps

def decorator1(fun):
    @wraps(fun)
    def wrapper(*args,**kwds):
        result = fun(*args,**kwds)
        for i,x in enumerate(result,1):
            x.extend( (i, x[0]+x[1]) )
        return result
    return wrapper

def decorator2(fun):
    @wraps(fun)
    def wrapper(*args,**kwds):
        for i,x in enumerate(fun(*args,**kwds),1):
            x.extend( (i, x[0]+x[1]) )
            yield x
    return wrapper
(这里我用来帮助维护装饰功能的一些元数据(不需要功能方面的数据),并作为编写示例的指南)

在第一个decorator中,由于结果是整个列表,我只需将额外的内容添加到每个元素并返回它,在第二个decorator中,我添加额外的内容,以维护生成器结构

加上这些,结果现在是
['val11','val12','val13',1','val11val12'],['val21','val22','val23',2',val21val22']


顺便说一句,因为你的2函数做同样的事情,我宁愿保留生成器,当我需要一个列表调用
list(readxls())
时,我也会在函数签名中添加两个额外的变量,默认值为那些字符串,以使函数更灵活