M. St.
M. St.

Reputation: 63

Closure not passing values. python 3

I trying to write a closure/nested function to make many similar plots. Now it seems that not all values are passed along as I get a 'UnboundLocalError' for one of the variables I try to pass on:

My code looks like:

def PlotFunc(x_name, y_name, fig_name=None, x_scale=None, y_scale=None, x_err=None, y_err=None, x_label=None, y_label=None, Binning=False):
    def Plot(Path=os.getcwd(), **kwargs):
        x =  np.linspace(0,20)
        y =  np.linspace(0,10)
        if x_scale is not None:
            xs = np.ones_like(x)
            x = x/xs
        if y_scale is not None:
            ys = np.ones_like(y)
            y=y/ys
        if x_err is not None:            #The error is raised here
            x_err =  np.ones_like(x)
        if y_err is not None:
            y_err = np.ones_like(y)
        if fig_name is None:
            fig_name = y_name+x_name+'.png'
        #and then I would do the plots
    return Plot

Plot_1 = PlotFunc('x', 'y', 'x-y-linspace.png', x_err=None, y_scale=np.ones(50), x_label=r'x', y_label=r'y')

running Plot_1 raises an error 'UnboundLocalError: local variable 'x_err' referenced before assignment' which I find odd as all the variables before have no issue being checked.

Am I doing something wrong or is there a limit how many variables can be passed in a closure in python3? I run python 3.6.9

Upvotes: 2

Views: 49

Answers (1)

Luke B
Luke B

Reputation: 1194

Since you assign a value to x_err in your function Plot(Path=os.getcwd(), **kwargs), it shadows the name from the outer scope. You can either pass your variables to your function, or you can change the name of your variables to not be the same in PlotFunc and Plot.

def PlotFunc(x_name, y_name, fig_name=None, x_scale=None, y_scale=None, x_err=None, y_err=None, x_label=None, y_label=None, Binning=False):
    def Plot(Path=os.getcwd(), **kwargs):
        x =  np.linspace(0,20)
        y =  np.linspace(0,10)
        if x_scale is not None:
            xs = np.ones_like(x)
            x = x/xs
        if y_scale is not None:
            ys = np.ones_like(y)
            y=y/ys
        if x_err is not None:
            x_err_other =  np.ones_like(x)
        if y_err is not None:
            y_err_other = np.ones_like(y)
        if fig_name is None:
            fig_name_other = y_name+x_name+'.png'
    return Plot

Plot_1 = PlotFunc('x', 'y', 'x-y-linspace.png', x_err=None, y_scale=np.ones(50), x_label=r'x', y_label=r'y')

Upvotes: 2

Related Questions