decorating a function while accessing the for loop variables within decorated function

时间:2018-03-23 00:23:12

标签: python python-3.x matplotlib decorator

Currently I have a bunch of functions that loop through images, makes some changes and then plots each image.

def second (images):
    for image in images:
        image = imread(image)
        image = image - 100
        plt.subplot(121)
        plt.imshow(image)
        plt.show()

Now I wanted to decorate these functions so that for there is another subplot for each image. A subplot with a normal image and a subplot with the transformed image.

However, I need to be able to access the image from the images iteration with the second function, and for each iteration use this image within the wrapper.

Is there a clean way to do this? I found a sort of hackish way to do this:

def plt_decorate(func):
    def func_wrapper(*args, **kwargs):
        images = args[0] 
        for image in images:
            im = imread(image)
            mng = plt.get_current_fig_manager() #this two lines
            mng.window.state('zoomed')          # are just to zoom plot
            plt.subplot(122),plt.imshow(im)
            if args[1:]:
                print( func([image], args[1:], **kwargs)) #can't return as loop ends
            else:
                print( func([image], **kwargs))
    return func_wrapper



@plt_decorate
def second (images):
    for image in images:
        image = imread(image)
        image = image - 100
        plt.subplot(121)
        plt.imshow(image)
        plt.show()

1 个答案:

答案 0 :(得分:1)

装饰器旨在在输入传递给您的函数之前转换输入。所以你应该继续循环images,改变它或引起一些副作用,然后将images传递给函数。

在你的情况下,它看起来像这样。

def plt_decorate(func):

    def func_wrapper(images):

        for image in images:
            im = imread(image)
            mng = plt.get_current_fig_manager()
            mng.window.state('zoomed')
            plt.subplot(122)
            plt.imshow(im)

        return func(images)

    return func_wrapper



@plt_decorate
def second (images):
    for image in images:
        image = imread(image)
        image = image - 100
        plt.subplot(121)
        plt.imshow(image)
        plt.show()