Opened 9 years ago

Closed 8 years ago

#5405 closed enhancement (fixed)

create a decorator for adding default keyword arguments to a function

Reported by: mhansen Owned by: cwitty
Priority: minor Milestone: sage-4.4.2
Component: misc Keywords:
Cc: mhansen, jason Merged in: sage-4.4.2.alpha0
Authors: Tim Dumol Reviewers: Mike Hansen
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Description (last modified by nthiery)

The typical usage of this decorator would be to be applied above a :obj:cached_method or :obj:cached_function decorator so that the correct cached object is returned.

Attachments (3)

trac_5405.patch (1.6 KB) - added by mhansen 9 years ago.
trac_5405-decorator-partial.patch (1.8 KB) - added by timdumol 8 years ago.
Adds module sage.misc.decorators with content specialize.
trac_5405-decorator-partial.2.patch (2.0 KB) - added by mvngu 8 years ago.
same as previous but with username

Download all attachments as: .zip

Change History (23)

Changed 9 years ago by mhansen

comment:1 Changed 9 years ago by nthiery

Hi Mike!

I am not so sure about the name, although I can't propose much better than default_values, or set_default_values.

Could it be generalized to handle both positional and non positional arguments?

I'd suggest to have the doc by starting with what the thing actually does, followed by the typical usage. Speaking of which: could you add an example of this typical usage? (it was not clear to me).

comment:2 Changed 9 years ago by jason

  • Cc jason added

comment:3 Changed 9 years ago by nthiery

  • Cc mhansen added; jason removed
  • Summary changed from [with patch, needs review] create a decorator for adding default keyword arguments to a function to [with patch, needs work] create a decorator for adding default keyword arguments to a function

Oops, should have set the subject to needs work. Done.

comment:4 Changed 8 years ago by jason

  • Cc jason added

comment:5 Changed 8 years ago by timdumol

Sorry if I don't get this right, but doesn't functools.partial already fulfill this purpose?

comment:6 Changed 8 years ago by jason

Do you mean something like this?

from functools import partial

def partial_dec(*args, **kwds):
    def p(f):
        return partial(f,*args,**kwds)
    return p
    
@partial_dec(b=2)
def f(a,b):
    return 10*a+b

f(4)

comment:7 Changed 8 years ago by timdumol

Actually I meant something like this:

from functools import partial

@partial(partial, b=4)
def f(a,b):
    return 10*a + b

f(4)

comment:8 Changed 8 years ago by jason

Cute. Very nice!

comment:9 Changed 8 years ago by jason

So now can you use @wraps or something so that g? works correctly below?

from functools import partial, wraps

@partial(partial, b=4)
def g(a,b):
    """Docs"""
    return 10*a + b

g?

comment:10 Changed 8 years ago by timdumol

This works, but it certainly isn't obvious:

from functools import partial, wraps

@partial(lambda x: wraps(x)(partial(partial, b = 4))(x))
def g(a,b):
    """Docs"""
    return 10*a + b

print(g(5))

g?

comment:11 Changed 8 years ago by jason

and at that point, I'd say

@default_keywords...
def g...

is nicer. However, one might use partial in the above decorator. I think our discussion is evidence for the usefulness of the idea on this ticket.

comment:12 Changed 8 years ago by timdumol

Yep. It's certainly much clearer. Using partial should deal with the positional and non-positional arguments thing.

comment:13 Changed 8 years ago by jason

So we've agreed that we should create a partial decorator that allows something like:

from sage.misc.decorators (or wherever) import partial

@partial(*args, **kwds) # Same as calling partial(g, *args, **kwds) and wrapping with @wraps
def g(a,b):
   ...

just works as expected.

comment:14 follow-up: Changed 8 years ago by timdumol

Perhaps a name of curry [1] would be better, since it prevents name collision with functools.partial? Then again, it supersedes functools.partial anyways.

[1] http://en.wikipedia.org/wiki/Currying

comment:15 in reply to: ↑ 14 ; follow-up: Changed 8 years ago by nthiery

  • Description modified (diff)

Thanks much for pointing out functools.partial and functool.wrapper; I have several other use cases for them!

Replying to timdumol:

Perhaps a name of curry [1] would be better, since it prevents name collision with functools.partial? Then again, it supersedes functools.partial anyways.

[1] http://en.wikipedia.org/wiki/Currying

I prefer partial, since curry does not really encompass the specialization of named arguments. It's really functools.partial, but made into a decorator.

comment:16 in reply to: ↑ 15 Changed 8 years ago by timdumol

I prefer partial, since curry does not really encompass the specialization of named arguments. It's really functools.partial, but made into a decorator.

Fair enough -- but just to clarify, functools.partial *is* a decorator, just that it doesn't update the documentation string.

Changed 8 years ago by timdumol

Adds module sage.misc.decorators with content specialize.

comment:17 Changed 8 years ago by timdumol

  • Report Upstream set to N/A
  • Status changed from needs_work to needs_review

Nevermind, functools.partial is not a decorator. My apologies.

This patch should do the trick. I named it specialize rather than partial, since partial conflicts with functools.partial.

comment:18 Changed 8 years ago by mhansen

  • Authors set to Tim Dumol
  • Reviewers set to Mike Hansen
  • Status changed from needs_review to positive_review

Looks good to me.

Changed 8 years ago by mvngu

same as previous but with username

comment:19 Changed 8 years ago by mvngu

  • Summary changed from [with patch, needs work] create a decorator for adding default keyword arguments to a function to create a decorator for adding default keyword arguments to a function

The patch trac_5405-decorator-partial.2.patch is the same as Tim's patch, but with his username.

comment:20 Changed 8 years ago by mvngu

  • Merged in set to sage-4.4.2.alpha0
  • Resolution set to fixed
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.