Path 使用装饰器在Python中行走路径
我很好奇decorators是如何工作的,所以我想看看它是否适合在路径中放置泛型函数。我想返回路径下以空格分隔的文件中最长的整数段(然后返回这个值或可能打印它)。这可能吗 我试图把东西倒回去,但没有成功。然后我很好奇,如果我把它放在函数外,它将如何工作。装饰师是否仅用于打印,或者您能否从他们那里返回以使此示例正常运行Path 使用装饰器在Python中行走路径,path,decorator,python,Path,Decorator,Python,我很好奇decorators是如何工作的,所以我想看看它是否适合在路径中放置泛型函数。我想返回路径下以空格分隔的文件中最长的整数段(然后返回这个值或可能打印它)。这可能吗 我试图把东西倒回去,但没有成功。然后我很好奇,如果我把它放在函数外,它将如何工作。装饰师是否仅用于打印,或者您能否从他们那里返回以使此示例正常运行 def walkPath(fn): def wrapper(*args, **kwargs): outside = None for dir
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])
这解释了我在没有decorator的情况下所做的事情,然后只是看看是否可以获得相同的功能,但使其通用。这意味着它不一定是一组文件中最长的单词,但可能是一组文件名中带有“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
您的问题是,您正试图拆分为外部循环及其主体,但在循环中有一个局部变量(
longest
)来比较数字。因此,您需要做的是使您的内部函数聚合结果。这意味着walkPath循环需要保存每次调用fn
的结果,并将其交给下一次调用,以便您可以在fn
中进行比较。最后,它应该吐出最后一次呼叫返回的内容。我想这就是你试图用外部所做的。我还从countL
中删除了path
参数,因为它没有做任何事情。您的示例应如下所示:
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)
的函数 您的问题是,您正试图拆分为外部循环及其主体,但在循环中有一个局部变量(longest
)来比较数字。因此,您需要做的是使您的内部函数聚合结果。这意味着walkPath循环需要保存每次调用fn
的结果,并将其交给下一次调用,以便您可以在fn
中进行比较。最后,它应该吐出最后一次呼叫返回的内容。我想这就是你试图用外部所做的。我还从countL
中删除了path
参数,因为它没有做任何事情。您的示例应如下所示:
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)
的函数 您必须决定要聚合到哪里以及如何返回数据。我会这样做:
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(步行路径(…)
此外,我将扩展比较改为
if os.path.splitext(filename)[1] == extension:
如果您在某处导入操作系统
停下来。重新阅读代码后,我必须问:
一个文件中是否可能有多个值对?如果是这样,我们必须使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(...))
再次说明。您必须决定要聚合到哪里以及如何返回数据。我会这样做:
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(步行路径(…)
此外,我将扩展比较改为
if os.path.splitext(filename)[1] == extension:
如果您在某处导入操作系统
停下来。重新阅读代码后,我必须问:
一个文件中是否可能有多个值对?如果是这样,我们必须使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(...))
再次说明。但是您实际上没有在包装中返回任何内容
…您也没有在countL
中返回任何内容…我试图提供一个有用的示例,但我无法从这个问题中看出您真正想要什么。我想你应该给出一两个目录结构的例子,其中的文件,以及你想要生成的输出。但是你实际上没有在wrapper
中返回任何东西……你也没有在countL
中返回任何东西……我试图提供一个有用的例子,但我无法从这个问题中看出你真正想要什么。我想你应该给出一个或两个目录结构的例子,其中的文件,以及你想要生成的输出。我想这就是我想要的。我必须稍后再尝试一下,让你知道。基本上,生成器可以返回任何东西,例如一个类,然后从外部处理您特别想要的东西,比如在本例中的max。@J Spen。基本上,decorator将返回值的函数转换为生成器,生成在遍历过程中找到的每个文件的值。无论我如何尝试,我都无法让它像这样正常工作。生成器只能调用next()一次。我做了一些更改:a)使参数传递更干净,b)使用splitext()
和c)抑制None
返回值,这些值来自countL()
中不存在的else
if
部分的if
。我已经创建了2个文件,它现在对我来说很有用…如果一个文件可以包含多个值对,我已经添加了一个替代实现(好的,实际上是2)。我想这就是我想要的。我必须稍后再尝试一下,让你知道