2

I have a function that uses functools LRU cache, but I want to pass in some non-input parameters e.g. "a"

import functools
import random

def foo(d, a):
    @functools.lru_cache()
    def bar(d):
        random.seed(d)
        nonlocal a
        a = []
        s = 0
        for i in range(100):
            r = random.random()
            a.append(r)
            s += r
        if s < 50:
            return True
        else:
            return False
    return bar(d)

But when I use these functions, "a" is not changed:

a = []
print(foo(random.randint(0, 100), a))
print(a)

What's going on? Also is this the right way to use functools, nested?

Update

I used this in the end i.e. with global and without foo:

@functools.lru_cache()
def bar(d):
    global a
    random.seed(d)
    ...

1 Answer 1

1

It does not change a because you are redefining it in the function. You are basically doing this:

def foo(a):
    a = [1, 2, 3]
    return a

a = []
foo(a)

So the outer a will remain as empty list after the function call. You may say but I'm using nonlocal keyword so I should be referencing to the original a. In fact, you are referencing to the parameter. So the effect is same as above code. If you run below code with and without nonlocal you can see what's going on:

def foo(a):
    def bar():
        # nonlocal a
        a = [1, 2, 3]
        print("bar", a)
    bar()
    print("foo", a)

a = []
foo(a)
print("global", a)

Outputs:

bar [1, 2, 3]
foo []
global []

And when you use nonlocal a:

bar [1, 2, 3]
foo [1, 2, 3]
global []

What you can do in your function is delete nonlocal a statement since it does not have any effect on the outer a and replace a = [] with a.clear().

Sign up to request clarification or add additional context in comments.

1 Comment

Gotcha, so you have to be careful not to re-initialise, as that would create a new list.

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.