【问题标题】:How to call a parent variable in a nested function如何在嵌套函数中调用父变量
【发布时间】:2021-07-27 03:38:56
【问题描述】:

我用cv2concurrent.futures 编写了一个去噪函数,用于我的训练和测试图像数据。

功能(目前)如下:

def denoise_single_image(img_path):
    nonlocal data
    img = cv2.imread(f'../data/jpeg/{data}/{img_path}')
    dst = cv2.fastNlMeansDenoising(img, 10,10,7,21)
    cv2.imwrite(f'../processed_data/jpeg/{data}/{img_path}', dst)
    print(f'{img_path} denoised.')
 
def denoise(data):
    img_list = os.listdir(f'../data/jpeg/{data}')
    with concurrent.futures.ProcessPoolExecutor() as executor:
        tqdm.tqdm(executor.map(denoise_single_image, img_list))

data 应为traintest,视需要而定; img_list 是该目录中所有图像名称的列表。

我需要在denoise()之前创建denoise_single_image()函数,否则denoise()将无法识别;但我需要在创建denoise_single_image() 之前定义data。这似乎是一个 catch-22,除非我能弄清楚如何告诉 denoise_single_image() 引用上一级存在的变量。

nonlocal 不起作用,因为它假定 data 已在此环境中定义。有没有办法让它工作?

【问题讨论】:

  • 数据不能全局范围的任何原因?你似乎不需要在任何地方修改它,所以这不是一个糟糕的用例。
  • @m.oulmakki 我试过globalnonlocal。虽然它(技术上)使用global 运行,但它似乎并不承认任何东西的存在。在global data 之后添加print(data) 没有返回任何内容。
  • 你不需要在定义denoise之前定义denoise_signal_image,只需在调用denoise之前。此外,nonlocal 适用于 词法 范围,而不是可能调用 denoise_single_image 的范围。参数data不是denoise_single_image所指的nonlocal变量data
  • 您有两个选择:将data 设为全局以便denoise 可以在调用denoise_single_image 之前设置其值,或者将data 设为denoise_single_image 的参数并使用类似@987654357 的参数@ 作为map 的第一个参数。
  • @chepner 我认为这会起作用,但tqdm.tqdm(executor.map(lambda x: denoise_single_image(data, x), img_list)) 似乎会停止该功能。几分钟后,我在输出目录中什么也看不到,而且我没有收到任何 {img_path} denoised 响应,即使在定义 denoise_single_image(data, img_path) 之后也是如此。

标签: python function scope nested python-nonlocal


【解决方案1】:

您可以将 executor.map 中的可迭代更改为参数元组,然后可以将其拆分到您的其他函数中。

executor.map(denoise_single_image, ((img_path, data) for img_path in img_list))

def denoise_single_image(inputs):
    img_path, data = inputs
    # etc

但在你的情况下,我只会像这样修改单个图像路径

executor.map(denoise_single_image, (f'jpeg/{data}/{img_path}' for img_path in img_list))

def denoise_single_image(img_path):
    img = cv2.imread(f'../data/{img_path}')
    dst = cv2.fastNlMeansDenoising(img, 10,10,7,21)
    cv2.imwrite(f'../processed_data/{img_path}', dst)
    print(f'{img_path.split('/')[-1]} denoised.')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-06
    • 2022-11-27
    • 2013-10-17
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多