如何在嵌套函数中调用父变量
Posted
技术标签:
【中文标题】如何在嵌套函数中调用父变量【英文标题】:How to call a parent variable in a nested function 【发布时间】:2021-07-27 03:38:56 【问题描述】:我用cv2
和concurrent.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
应为train
或test
,视需要而定; img_list
是该目录中所有图像名称的列表。
我需要在denoise()
之前创建denoise_single_image()
函数,否则denoise()
将无法识别;但我需要在创建denoise_single_image()
之前定义data
。这似乎是一个 catch-22,除非我能弄清楚如何告诉 denoise_single_image()
引用上一级存在的变量。
nonlocal
不起作用,因为它假定 data
已在此环境中定义。有没有办法让它工作?
【问题讨论】:
数据不能全局范围的任何原因?你似乎不需要在任何地方修改它,所以这不是一个糟糕的用例。 @m.oulmakki 我试过global
和nonlocal
。虽然它(技术上)使用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)
之后也是如此。
【参考方案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.')
【讨论】:
以上是关于如何在嵌套函数中调用父变量的主要内容,如果未能解决你的问题,请参考以下文章