1

I want to write a function which returns itself a function.

from types import FunctionType
import numpy as np    

def outer_function(beta: np.array, K: np.array, increment: str,
                   augmented: bool, prior: FunctionType=None, **kwargs) -> FunctionType:
            
        def g(x: float) -> float:
            if prior is None:
                prior = x**2
            return beta+x+prior
        return g

The problem I'm encountering is that certain variables of the outer function are not in the scope of the inner, while others are

 test = outer_function(np.array(0), np.array([1,2,3]), increment="hello", augmented=False, prior=None, alpha=10)

 In [91]: pdb.runcall(test, 10)
> <ipython-input-87-16d13c025c81>(5)g()
-> if prior is None:
(Pdb) print(prior)
*** NameError: name 'prior' is not defined
(Pdb) dir()
['beta', 'x']
(Pdb) print(x)
10
(Pdb) 

as you can see I only get the variable x and beta. But all the other variables are not seen by g. How can I make all variables of the outer accessible for the inner?

1
  • I'm sure that you would have seen the error: UnboundLocalError: local variable 'prior' referenced before assignment before you started debugging. If you had searched for that you would have seen answers on stackoverflow. Commented Aug 28, 2021 at 11:05

2 Answers 2

2

The Python compiler detects prior = in the g function and assumes that "prior" is a local variable, you need to tell the compiler that you want to access it from the outer function/scope using nonlocal

    def g(x: float) -> float:
        nonlocal prior
        if prior is None:
            prior = x**2
        return beta+x+prior
Sign up to request clarification or add additional context in comments.

Comments

1

Its because you are possibly reassigning prior. The python compiler marks prior as local because of that (and ignores the parameter to outer_function)

Here is one fix:

def outer_function(beta: np.array, K: np.array, increment: str,
                   augmented: bool, prior: FunctionType=None, **kwargs) -> FunctionType:
            
        def g(x: float) -> float:
            p = prior
            if p is None:
                p = x**2     # reassign to p
            return beta + x + p
        return g

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.