0

I have a python function which is caching results based on the parameter passed. The issue is, fval() can return different values depending on other factors. But the test() is still sending me stale values. How do I ensure, the parameter v is getting the latest values from fval()

@cached(60*5)
def test(a,v=fval()):
  print "inside function"
  return a,v

r = test(2)
inside test function
print r
(2, 5)

print fval()
7

r = test(2) . #This time I am expecting v to be 7, but it isnt
print r 
(2,5)

I am expecting r to print (2,7) instead. How do I ensure, latest values are being sent as a parameter to the cached function ?

Rahul
  • 11,129
  • 17
  • 63
  • 76

2 Answers2

0

Optional values are evaluated when the function itself is evaluated for all functions in Python. The usual solution is to provide a value that represents nothing, then check for it:

@cached(60*5)
def test(a, v=None):
    if v is None:
        v = fval()

    print "inside function"
    return a, v

If, after that, you also expect cached to act on the final value of fval() instead of the absence of a second argument, you’ll need to do something like this:

@cached(60*5)
def _test(a, v):
    print "inside function"
    return a, v

def test(a, v=None):
    if v is None:
        v = fval()

    return _test(a, v)
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Hey, I thought [your answer](https://stackoverflow.com/questions/195149/is-it-possible-to-sandbox-javascript-running-in-the-browser/24660713#24660713) was a useful, creative contribution that deserves to stay (it was a unique approach for a similar problem I had) - a bit odd, but a very interesting option to keep in mind, was it really unsalvageable for some reason? – CertainPerformance Mar 11 '19 at 06:04
  • @CertainPerformance: I no longer think it’s a robust approach, now that I’ve seen some of the direction web workers are going, and haven’t looked into whether it can still be a safe approach – so it’s safer for me not to recommend it at all for now. Will try to find time to check it more thoroughly. (Even when I had the same problem at a job, my main choice of defense was a sandboxed iframe, not a web worker.) – Ry- Mar 11 '19 at 06:52
0

It's because of this line:

def test(a,v=fval()):

In Python, default arguments are resolved once, at function definition.

You'll probably need to do something like this:

def test(a, v=None):
    if v is None:
        v = fval()

    # the rest here
gmds
  • 19,325
  • 4
  • 32
  • 58