2

I'm trying to learn decorators and partial, and I think I make some sense. I understand decorators as a way to add additional functionality to an object by passing in the arguments from the function that calls the decorator into the nested function in the decorator. My understanding of partial is that I can use when I want to reduce the number of parameters to a function. So far so good. But then I saw this code snippet, and I don't understand why _inner takes in only start and end. Why not pos? In my head, it makes sense if this should be the third parameter. :

def annealer(f): 
    def _inner(start, end): 
        return partial(f, start, end)
    return _inner

@annealer
def sched_lin(start, end, pos):
    return start + pos*(end-start)

f = sched_lin(1,2)
f(1)
OUTPUT: 2
duplode
  • 33,731
  • 7
  • 79
  • 150
XRaycat
  • 1,051
  • 3
  • 16
  • 28
  • 3
    The idea here is that you can call `f(0)`, `f(0.2)`, ... `f(1)`, passing the `pos` parameter. If you pass all 3 parameters to make the partial, it would be a constant function... – Thierry Lathuille Mar 29 '19 at 19:47
  • I think I was I bit unclear in my question, sorry for that. I believe I understand that part(maybe). It's more why does `_inner` only takes `start` and `end` in the argument and not `pos`. In all the example I have seen about decorators, the nested function has the same number of parameters as the calling function ( `def sched_lin(start, end, post)`) – XRaycat Mar 29 '19 at 19:53
  • 3
    `annealer` basically curries its function to some extent. Instead of `sched_lin` being a 3-argument function, it's now a 2-argument function that returns a one-argument function. That is, instead of calling `sched_lin(1,2,3)`, you now call `sched_lin(1,2)(3)`. IMO, having the decorator modify the signature of the decorated function is just confusing. – chepner Mar 29 '19 at 19:56
  • 2
    In other words, the `annealer` decorator returns a new function that has its first two arguments supplied automatically. Since the original `sched_lin()` function had a total of three parameters defined, the decorated version only needs to be passed with the last one, `pos`. – martineau Mar 29 '19 at 20:13
  • 1
    @chepner: The confusion, I think, is owed mostly to the uninformative name: the decorator doesn’t *make* the underlying function into an annealer. I’ve used a similar decorator for any number of arguments (it returns `partial(partial,f)`), but based on the bifurcated argument list I called it `curry2`! – Davis Herring Mar 30 '19 at 04:00

0 Answers0