Reputation: 63
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
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