在while循环中使用生成器,并在每次生成后进行评估

2024-06-16 10:10:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用Python在CAD程序中打开一些文件。因为当我一次打开太多文件时程序会崩溃,所以当文件大小总和超过某个值时,我希望脚本停止打开我生成的列表中的文件。你知道吗

到目前为止,我掌握的情况如下:

我正在把日志文件转换成一个列表。它包含用逗号分隔的文件路径:

fList = []

with open('C:/Users/user/Desktop/log.txt', 'r') as f:
    fList = f.read().split(',')
    with suppress(ValueError, AttributeError):
        fList.remove('')
    fcount = len(fList)

这是我用来迭代零件列表的生成器:

def partGenerator(partList):
    for file in partList:
        yield file

在这里,当文件大小之和小于2500000比特时,我尝试循环遍历文件:

count = 0
progression = 0
storage = 0

while storage < 2500000:
    for file in partGenerator(fList):
        name = os.path.basename(file)
        storage += os.path.getsize(file)
        print(f'Auslastung: {storage} bite / 2500000 bite')
        oDoc = oApp.Documents.Open(file)

        progression += 1
        percent = round(100 * progression / fcount)
        print(f'Fortschritt: {progression} / {fcount} ({percent} %) - {name}')

所发生的情况是,文件在CAD软件中适当地打开,但在超过while条件后它们不会停止。我的猜测是,while条件是在列表的条目用完之后计算的,而不是在每个条目之后计算的,就像我要做的那样。你知道吗

帮助正确的语法会很棒!你知道吗

我最终想要的是:

我想使用这个脚本的方式,它打开一些文件,每当我手动关闭一个在CAD程序,它打开从我的列表中的下一个,直到列表用尽。你知道吗


Tags: 文件程序脚本列表with情况storagefile
2条回答

您的while条件从未被检查过,不,因为for循环从不允许Python检查。for循环从生成器函数中获取元素既不在这里也不在那里。你知道吗

如果条件仍然成立,则需要检查for循环中的

for file in partGenerator(fList):
    name = os.path.basename(file)
    storage += os.path.getsize(file)
    if storage >= 2500000:
        # wait for input before continuing, then reset the storage amount
        input("Please close some files to continue, then press ENTER")
        storage = 0

Python不会检查while条件,直到while ...:语句下的块中的完整套件(一系列语句)完成运行或执行continue语句,因此while条件确实不适合这里。你知道吗

在上面的示例中,我使用了低技术的input()函数来请求运行脚本的人在之后按ENTER。这将取决于oDoc.Documents作为API实际提供了什么,以确定是否可以使用它来检测文件已关闭。你知道吗

如果要使用生成器函数,请让它跟踪文件大小。你甚至可以让它从CSV文件中读取这些内容。我会使用^{} module来处理拆分和进程,顺便说一下:

import csv


def parts(logfile):    
    with open(logfile, newline='') as f:
        reader = csv.reader(f)
        files = [column for row in reader for column in row if column]
    fcount = len(files)
    storage = 0
    for i, filename in enumerate(files):
        storage += os.path.getsize(file)
        if storage >= 2500000:
            input("Please close some files to continue, then press ENTER")
            storage = 0
        print(f'Auslastung: {storage} bite / 2500000 bite')
        yield file
        print(f'Fortschritt: {i} / {fcount} ({i / fcount:.2%}) - {name}')

那就用吧

for file in parts('C:/Users/user/Desktop/log.txt'):
    oDoc = oApp.Documents.Open(file)

请注意,打开的文件的绝对数量是操作系统限制的数量,而不是这些文件的大小。你知道吗

在Martijn Pieters的帮助下,我想出了一个非常适合我的方法。我是个编程高手,所以我花了一段时间才明白这个问题。以下是最终表现良好的:

fList = []

with open('C:/Users/jhoefler/Desktop/log.txt', 'r') as f:
    fList = f.read().split(',')
    with suppress(ValueError, AttributeError):
        fList.remove('')
    fcount = len(fList)

count = 0
progression = 0

for file in fList:

    name = os.path.basename(file)
    if oApp.Documents.Count < 10:
        oDoc = oApp.Documents.Open(file)
    else:
        pCount = oApp.Documents.LoadedCount
        fCount = oApp.Documents.LoadedCount
        while fCount == pCount:
            time.sleep(1)
            pCount = oApp.Documents.LoadedCount
        oDoc = oApp.Documents.Open(file)

    progression += 1
    percent = round(100 * progression / fcount)
    print(f'Fortschritt: {progression} / {fcount} ({percent} %) - {name}')

我确信有一种更优雅的方法来解决这个问题,但它对我的需要很有效。你知道吗

相关问题 更多 >