Как получить доступ к локальной переменной, сгенерированной внутри цикла «while True: try / break» после выхода из него?

#python #function #variables #scope #global-variables

#python #функция #переменные #область видимости #глобальные переменные

Вопрос:

Я написал модуль, который принимает все изображения TIFF в каталоге, усредняет по всем кадрам в каждом файле изображения и сохраняет усредненные изображения в автоматически сгенерированном подкаталоге, указанном outputPath :

 def average_tiff_frames(inputPath):
    '''
    This function opens all TIFF image files in a directory, averages over all frames within each TIFF file,
    and saves the averaged images to a subdirectory.
    
    Parameters
    ----------
    inputPath : string
        Absolute path to the raw TIFF files
    '''
    import datetime
    import os
    
    import numpy as np

    from PIL import Image
    
    
    # Read image file names, create output folder
    while True:
        try:
            inputPath = os.path.join(inputPath, '')    # Add trailing slash or backslash to the input path if missing
            filenames = [filename for filename in os.listdir(inputPath)
                            if filename.endswith(('.tif', '.TIF', '.tiff', '.TIFF'))
                            and not filename.endswith(('_avg.tif'))]
            outputPath = os.path.join(inputPath, datetime.datetime.now().strftime('%Y%m%dT%H%M%S'), '')
            os.mkdir(outputPath)
            break
        except FileNotFoundError:
            print('TIFF file not found - or - frames in TIFF file already averaged (file name ends with "_avg.tif")')

    # Open image files, average over all frames, save averaged image files
    for filename in filenames:
        img = Image.open(inputPath   filename)

        width, height = img.size
        NFrames = img.n_frames

        imgArray = np.zeros((height, width))    # Ordering of axes: img.size returns (width, height), np.zeros takes (rows, columns)
        for i in range(NFrames):
            img.seek(i)
            imgArray  = np.array(img)
            i  = 1
        imgArrayAverage = imgArray / NFrames

        imgAverage = Image.fromarray(imgArrayAverage)
        imgAverage.save(outputPath   filename.rsplit('.')[0]   '_avg'   '.tif')

        img.close()

    return outputPath
    print('Averaged TIFF images have been saved to '   outputPath   '. The output path is returned as a string to the variable "outputPath".')
  

После выполнения модуля я хочу, чтобы outputPath (т. Е. назначенная ему строка) была доступна для дальнейших шагов. Однако при выполнении

 average_tiff_frames(inputPath)
print(outputPath)
  

Я получаю следующую ошибку:

 ---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-99d0a947275c> in <module>()
      1 inputPath = '/home/user/Desktop/data/'
      2 average_tiff_frames(inputPath)
----> 3 print(outputPath)

NameError: name 'outputPath' is not defined
  

В чем здесь проблема?

Моей первой мыслью было, что она outputPath локальна для while True: try цикла и уничтожается после break , поэтому я создал экземпляр пустой строки outputPath = '' прямо перед циклом, но это не помогло.

Комментарии:

1. Ответ Дэвида решает вашу проблему, но, пожалуйста, попробуйте минимизировать свой код в следующий раз. Вам не нужно показывать 50 строк кода только для воспроизведения вашей проблемы. Это можно упростить до 2-3 строк, и это также поможет вам понять, что происходит.

2. Да, в любом случае, это был глупый вопрос. Удалено.

Ответ №1:

Вы не пытаетесь получить доступ к переменной вне цикла, вы пытаетесь получить к ней доступ полностью из метода. Метод возвращает искомое значение, поэтому установите это значение в переменную:

 outputPath = average_tiff_frames(inputPath)

print(outputPath)
  

Или просто распечатать его напрямую:

 print(average_tiff_frames(inputPath))