Использование генератора в цикле while и оценка после каждого выхода - PullRequest
2 голосов
/ 07 марта 2019

Я использую 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)

Это генератор, который я использую для итерации по partList:

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}')

Что происходит, так это то, что файлы автоматически открываются в программном обеспечении САПР, но они не останавливаются после превышения условия. Я предполагаю, что условие while оценивается после того, как в списке заканчиваются записи, а не после каждой записи, как я.

Справка по правильному синтаксису была бы отличной!

Что я ищу в конечном итоге:

Я хотел бы использовать этот скрипт таким образом, чтобы он открывал некоторые файлы и всякий раз, когда я вручную закрывал один в программе CAD, он открывал следующий из моего списка, пока список не был исчерпан.

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

Ваше условие 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. Я бы использовал модуль csv для обработки разбиения и прогресса, кстати:

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)

Обратите внимание, что абсолютное количество открытых файлов - это то, что ограничивает ваша ОС, а не размер этих файлов.

0 голосов
/ 07 марта 2019

При содействии Мартина Питерса я придумал что-то, что идеально подходит для меня. Я новичок в программировании, поэтому мне понадобилось время, чтобы понять проблему. Вот что проснулось в итоге:

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}')

Я уверен, что есть более элегантный способ решения проблемы, но он отлично работает для моих нужд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...