2

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

7
  • Which variables before? Commented Jul 27, 2020 at 13:52
  • @HeapOverflow No other variables are defined before here. This is just a minimal running example that reproduces the error. Also there are no global variables in the python file I run this function in if that is what you mean. Commented Jul 27, 2020 at 14:01
  • You are talking about "variables before". I'm asking which ones you mean. Commented Jul 27, 2020 at 14:02
  • Ahh I mean x_scale and y_scale they don't raise the same error. Commented Jul 27, 2020 at 14:03
  • 1
    I wouldn't phrase it like that, but I guess you mean the right thing. You assign to x_err, making x_err a local variable in the function. And you're trying to access it before the assignment. Commented Jul 27, 2020 at 14:23

1 Answer 1

2

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') 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.