Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 发电机不能自动排气_Python_Generator - Fatal编程技术网

Python 发电机不能自动排气

Python 发电机不能自动排气,python,generator,Python,Generator,我尝试连接两个函数,一个遍历目录并查找文件名,将名称发送到检查文件是否超过30天的函数,如果不满足条件则删除文件 我试着练习使用生成器,从一个函数到另一个函数实现优雅的流程,但它打破了for循环和函数,因此需要重新激活函数 import os from datetime import datetime,timedelta PATH = os.path.abspath(os.path.dirname(__file__)) + '\folder' def get_dates(p): f

我尝试连接两个函数,一个遍历目录并查找文件名,将名称发送到检查文件是否超过30天的函数,如果不满足条件则删除文件

我试着练习使用生成器,从一个函数到另一个函数实现优雅的流程,但它打破了for循环和函数,因此需要重新激活函数

import os
from datetime import datetime,timedelta

PATH = os.path.abspath(os.path.dirname(__file__)) + '\folder'


def get_dates(p):
    for path, dirs, files in os.walk(p):
        for file in files:
                fullname = path+ '\\'+file
                mtime = os.stat(fullname).st_ctime

                yield (delete_not_needed(fullname, mtime))


def delete_not_needed(fullname, mtime):
    file_time = datetime.fromtimestamp(mtime)
    if datetime.today()-file_time> timedelta(days=30):
        os.remove(fullname)

if __name__ == '__main__':
    next(get_dates(PATH))

如何连接这些函数?

您应该返回文件名,然后在生成器上迭代以删除这些文件

def delete_not_needed(fullname, mtime):
    file_time = datetime.fromtimestamp(mtime)
    if datetime.today()-file_time> timedelta(days=30):
        return fullname

if __name__ == '__main__':
    files_to_delete = get_dates(PATH)
    for file in files_to_delete:
        if file:
            os.remove(file)

您应该返回文件名,然后在生成器上迭代以删除这些文件

def delete_not_needed(fullname, mtime):
    file_time = datetime.fromtimestamp(mtime)
    if datetime.today()-file_time> timedelta(days=30):
        return fullname

if __name__ == '__main__':
    files_to_delete = get_dates(PATH)
    for file in files_to_delete:
        if file:
            os.remove(file)

您需要在循环中调用生成器:

for _ in get_dates(PATH):
    pass

这似乎是一个非常不必要的发电机使用,因为它不会产生任何东西。它应该只是一个普通函数,用于调用循环中不需要的delete\u。

您需要在循环中调用生成器:

for _ in get_dates(PATH):
    pass

这似乎是一个非常不必要的发电机使用,因为它不会产生任何东西。它应该只是一个普通函数,调用循环中不需要的delete\u。

我认为代码的总体结构不是最优的。我建议您尝试用一个简单的句子解释每个函数/生成器的作用,将其放入docstring中,并相应地命名函数。这将帮助别人和你自己理解你到底在做什么

在您最初的示例中,get_dates并没有获取日期,它实际上删除了所有不需要的文件,并且不会产生任何结果。那么为什么它应该是一个发电机呢?一个带有循环的标准函数就可以实现这一点,而不需要手动将其耗尽

不过,在这种情况下,生成器可能很有用:它采用路径,只生成超过30天的文件名。然后,此生成器的调用方选择如何处理它们在您的情况下,删除它们

import os
from datetime import datetime,timedelta

PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'folder')
DELTA_30_DAYS = timedelta(days=30)

def get_old_files(p, age=DELTA_30_DAYS):
    """
    Yields the fullnames of all files in p older than age
    """
    for path, dirs, files in os.walk(p):
        for file in files:
                fullname = os.path.join(path, file)
                mtime = os.stat(fullname).st_ctime
                file_time = datetime.fromtimestamp(mtime)
                if datetime.today()-file_time> age:
                    yield fullname

if __name__ == '__main__':
    for fullname in get_old_files(PATH):
        os.remove(fullname)
请注意,发电机应在主部分的回路中使用


另外请注意get_old_文件中的可选参数age,这使生成器更加灵活。

我认为代码的总体结构不是最优的。我建议您尝试用一个简单的句子解释每个函数/生成器的作用,将其放入docstring中,并相应地命名函数。这将帮助别人和你自己理解你到底在做什么

在您最初的示例中,get_dates并没有获取日期,它实际上删除了所有不需要的文件,并且不会产生任何结果。那么为什么它应该是一个发电机呢?一个带有循环的标准函数就可以实现这一点,而不需要手动将其耗尽

不过,在这种情况下,生成器可能很有用:它采用路径,只生成超过30天的文件名。然后,此生成器的调用方选择如何处理它们在您的情况下,删除它们

import os
from datetime import datetime,timedelta

PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'folder')
DELTA_30_DAYS = timedelta(days=30)

def get_old_files(p, age=DELTA_30_DAYS):
    """
    Yields the fullnames of all files in p older than age
    """
    for path, dirs, files in os.walk(p):
        for file in files:
                fullname = os.path.join(path, file)
                mtime = os.stat(fullname).st_ctime
                file_time = datetime.fromtimestamp(mtime)
                if datetime.today()-file_time> age:
                    yield fullname

if __name__ == '__main__':
    for fullname in get_old_files(PATH):
        os.remove(fullname)
请注意,发电机应在主部分的回路中使用


另请注意get_old_文件中的可选参数age,这使生成器更灵活。

要使生成器在for循环中遍历它,请使用它。下一步只取第一个无关项,但在windows上,+'\folder'可能应该是+'/folder'@tobias_k。应该是os.path.sep才能跨平台,或者只使用pathlib。使用os.path.join连接目录和子目录名。delete\u not\u needed不返回任何内容,您将得到什么?要耗尽生成器,请在for循环中对其进行迭代。下一步只取第一个无关项,但在windows上,+'\folder'可能应该是+'/folder'@tobias_k。应该是os.path.sep才能跨平台,或者只使用pathlib。使用os.path.join连接目录和子目录名。delete_not_needed不返回任何内容,您将得到什么?当文件不应删除时,您需要跳过它返回的None值。重用@waltexwq的函数名不是最好的主意。正如我在对这个问题的评论中指出的那样,get_dates的名字不好。它什么也没有得到,现在它得到了旧文件的名称。Dette_not_needed不再删除任何内容,但会返回文件名或None,具体取决于文件的年龄。@Pierre Antoine,是的,从名称角度来看,与他们的工作相比,它们不是很好的选择。当文件不应删除时,您需要跳过它返回的None值。重用@waltexwq的函数名不是最好的主意。正如我在对这个问题的评论中指出的那样,get_dates的名字不好。它什么也没有得到,现在它得到了旧文件的名称。Dette_not_needed不再删除任何内容,而是根据文件的年龄返回文件名或不返回文件名。@Pierre Antoine,是的,从名称角度来看,与他们的工作相比,他们不是很好的选择。谢谢,我知道-我这边有很多错误,命名是我常见的陷阱。我会使用你的建议。谢谢你,我知道——我这边有很多错误,命名是我常见的陷阱。我会采纳你的建议。