1

我很好奇装饰器是如何工作的,所以想看看它是否可以将通用函数放置在行走路径中。我想在路径下方的空格分隔文件中返回最长的整数段(然后返回此值或可能打印它)。这可能吗?

我试图在 countL 中返回东西但没有成功。然后很好奇如果我把它放在函数之外,这将如何工作。装饰器仅用于打印还是您可以从他们那里返回以使此示例正常运行?

def walkPath(fn):
    def wrapper(*args, **kwargs):
        outside = None
        for dirname, dirnames, filenames in os.walk(args[0]):
            for filename in filenames:
                fn(filename, dirname, outside, *args, **kwargs)
    return wrapper

@walkPath
def countL(filename, dirname, outside, path, extension = '.wrd'):
    if (filename[-4:]  == extension):
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            if (int(temp[1]) - int(temp[0]) > longest):                
                outside = int(temp[1]) - int(temp[0])

这解释了我在没有装饰器的情况下所做的事情,然后只是看看你是否可以获得相同的功能但使其通用。这意味着它不一定是一组文件中最长的单词,但可能是一组文件名中带有单词“s”的文件。只是不知道如何正确处理最长的外部变量,或者是否可以使用装饰器。

def countLength(path, extension = '.wrd'):
    longest = 0
    for dirname, dirnames, filenames in os.walk(path):
        for filename in filenames:
            if (filename[-4:]  == extension):
                with open(os.path.join(dirname, filename), 'r') as input:
                    data = input.readlines()
                for i in range(len(data)):
                    temp = data[i].split()
                    if (int(temp[1]) - int(temp[0]) > longest):
                        longest = int(temp[1]) - int(temp[0])
    return longest
4

2 回答 2

1

您的问题是,您试图拆分为外部循环及其主体,但在循环内您有一个局部变量 ( longest) 来比较数字。所以你需要做的是让你的内部函数聚合结果。这意味着 walkPath 循环需要保存每次调用的结果fn并将其交给下一次调用,因此您可以 fn. 最后它应该吐出最后一次调用返回的内容。我想这就是你想要做的outside。我还path从 中删除了参数countL,因为它没有做任何事情。你的例子应该像这样工作:

def walkPath(fn):
    def wrapper(outside, *args, **kwargs):
        for dirname, dirnames, filenames in os.walk(args[0]):
            for filename in filenames:
                outside = fn(outside, filename, dirname, *args, **kwargs)
        return outside
    return wrapper

@walkPath
def countL(outside, filename, dirname, extension = '.wrd'):
    if (filename[-4:]  == extension):
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            if (int(temp[1]) - int(temp[0]) > outside):                
                outside = int(temp[1]) - int(temp[0])
    return outside

然后,您将不得不调用类似countL(0).

于 2012-05-11T05:14:26.783 回答
0

您必须决定要聚合的位置以及如何返回数据。我会这样做:

def walkPath(fn):
    def wrapper(walkroot, *args, **kwargs):
        for dirname, dirnames, filenames in os.walk(walkroot):
            for filename in filenames:
                res = fn(filename, dirname, *args, **kwargs)
                if res is not None: yield res
    return wrapper

@walkPath
def countL(filename, dirname, extension='.wrd'):
    if os.path.splitext(filename)[1] == extension:
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            return int(temp[1]) - int(temp[0])

现在,调用者walkPath()得到一个生成器,它从每个文件中产生一个“增量值”。所以你可以很容易地找到最大值max(walkPath(...))

此外,我将扩展比较更改为

if os.path.splitext(filename)[1] == extension:

为你提供了import os某个地方。


停止。重新阅读代码后,我不得不问:

一个文件中可能有多个值对吗?如果是这样,我们必须countL()返回一个生成器。

@walkPath
def countL(filename, dirname, extension='.wrd'):
    if os.path.splitext(filename)[1] == extension:
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            yield int(temp[1]) - int(temp[0])

现在装饰countL()器返回一个生成器的生成器,所以我们必须这样做

max(value for filegen in countL(...) for value in filegen)

或者,我们可以更改walkPath()

def walkPath(fn):
    def wrapper(walkroot, *args, **kwargs):
        for dirname, dirnames, filenames in os.walk(walkroot):
            for filename in filenames:
                for item in fn(filename, dirname, *args, **kwargs):
                    yield item
    return wrapper

以便它产生每次调用的项目fn()。还不够

max(countL(...))

再次。

于 2012-05-11T05:26:12.563 回答