装饰图像处理函数时,如何访问原函数for循环的迭代变量?
我明白你想要实现的效果——给图像处理函数加装饰器,让每张图都能同时展示原图和变换后的结果,而且希望代码更简洁优雅。你当前的实现确实有点绕,主要问题在于原函数和装饰器都在处理循环,而且调用原函数的方式不够直观。咱们可以通过职责分离来优化:让装饰器负责循环遍历、绘图布局和原图展示,原函数只专注于单张图像的变换逻辑,这样代码会清晰很多。
优化方案代码
import matplotlib.pyplot as plt from skimage.io import imread # 也可以替换成你使用的其他图像读取库 def plt_decorate(func): def wrapper(images, *args, **kwargs): for image_path in images: # 读取原图 original_img = imread(image_path) # 调用原函数处理单张图像,得到变换后的结果 transformed_img = func(image_path, *args, **kwargs) # 设置窗口最大化 mng = plt.get_current_fig_manager() mng.window.state('zoomed') # 绘制子图:左图显示变换后,右图显示原图 plt.subplot(121) plt.imshow(transformed_img) plt.title("变换后图像") plt.subplot(122) plt.imshow(original_img) plt.title("原图") plt.tight_layout() # 自动调整子图间距,避免标题重叠 plt.show() return wrapper # 修改原函数:只处理单张图像的读取和变换,去掉循环和plt.show @plt_decorate def second(image_path): img = imread(image_path) img = img - 100 return img # 返回变换后的图像,交给装饰器处理绘图
为什么这个方案更简洁?
- 职责清晰:装饰器包揽了所有和绘图、循环相关的逻辑,原函数只需要专注于图像的变换操作(比如这里的减100),代码更易维护和扩展。
- 避免重复逻辑:原来的代码里原函数和装饰器都在读取图像、处理循环,现在只在装饰器里读一次原图,原函数只处理自己需要的变换逻辑。
- 调用更直观:装饰器直接遍历传入的
images列表,每张图单独处理,不需要像之前那样把单张图像包装成列表传给原函数。
进一步优化(可选)
如果想让原函数直接接收已读取的图像数组,而不是路径,可以调整装饰器和原函数,让原函数的逻辑更纯粹:
def plt_decorate(func): def wrapper(images, *args, **kwargs): for image_path in images: original_img = imread(image_path) # 把已读取的原图传给原函数 transformed_img = func(original_img, *args, **kwargs) # 后续绘图逻辑和之前一致 mng = plt.get_current_fig_manager() mng.window.state('zoomed') plt.subplot(121) plt.imshow(transformed_img) plt.title("变换后图像") plt.subplot(122) plt.imshow(original_img) plt.title("原图") plt.tight_layout() plt.show() return wrapper @plt_decorate def second(img): # 直接处理图像数组,完全专注于变换逻辑 return img - 100
内容的提问来源于stack exchange,提问作者Moondra
相关产品推荐
相关产品推荐

