Как вернуться в python, читая несколько. xml файлов - PullRequest
0 голосов
/ 03 мая 2020

Я пишу скрипт в Python, который будет go через папку и подпапку, читает только XML файлы с более чем 100 файлами. Если я жестко запрограммировал этот код вне функции, он считывает все 100 XML файлов в temp0, однако, если я помещаю этот код в функцию и использую return, функция всегда возвращает только один 1 файл, я имею в виду, что он читает только один файл. Кто-нибудь может объяснить, почему «возврат» работает таким образом? Заранее спасибо.

def raw_input(doc):
    for root, dirs, packs in doc:
        for files in packs:
            if files == 'abc.xml':
                filename = os.path.join(root, files)
                open_file = open(filename, 'r')
                perpX_ = open_file.read()
                # print(perpX_)
                outputX_ = re.compile('<test (.*?)</text>', re.DOTALL | re.IGNORECASE).findall(perpX_)
                temp0 = str("|".join(outputX_))
                #print(temp0)
                return temp0

doc=os.walk('./data/')
raw_input(doc)

temp0 = raw_input(doc)
print(temp0)

1 Ответ

2 голосов
/ 03 мая 2020

return возвращает результат функции, поэтому, как только достигается return, Python выходит из функции и принимает результат выражения рядом с return как вывод функции.

У вас есть return внутри for l oop, что означает, что оно будет достигаться на каждой итерации, но интерпретатор Python предполагает, что temp0 будет конечным результатом вызова вашей функции, поэтому он выходит.

Вы можете вернуть несколько значений в списке, например, так:

def raw_input(doc):
    result = []    # this is where your output will be aggregated
    for root, dirs, packs in doc:
        for files in packs:
            if files == 'abc.xml':
                filename = os.path.join(root, files)
                open_file = open(filename, 'r')
                perpX_ = open_file.read()
                # print(perpX_)
                outputX_ = re.compile('<test (.*?)</text>', re.DOTALL | re.IGNORECASE).findall(perpX_)
                # We append the output for current file to the list
                result.append(str("|".join(outputX_)))
    # And now we return our string, at the end of the function.
    # AFTER the for loops
    return '|'.join(result)

doc=os.walk('./data/')

temp0 = raw_input(doc)
print(temp0)

Таким образом, вы получите свои выходные данные в виде одной строки.

Также есть такая вещь, как generator. Генератор - это объект, который можно повторять. Вы можете заставить свой код оценивать лениво (по требованию):

# now raw_input is a generator
def raw_input(doc):
    # we don't need a storage now
    for root, dirs, packs in doc:
        for files in packs:
            if files == 'abc.xml':
                filename = os.path.join(root, files)
                open_file = open(filename, 'r')
                perpX_ = open_file.read()
                outputX_ = re.compile('<test (.*?)</text>', re.DOTALL | re.IGNORECASE).findall(perpX_)
                # now we yield current value and function temporary stops its evaluation
                yield str("|".join(outputX_))

doc=os.walk('./data/')
results = raw_input(doc)
# now results is a generator. It is not evaluated yet
# you can get first output like this:
first_out = next(results)
# and then the second:
second_out = next(results)
# or iterate over it, just like over a casual list:
for res in results:
    print(res)
# note that it will iterate only over next values
# (excluding first and second ones, since it doesn't have access to them anymore)

# and now res is empty (we've reached the end of generator)
...