[Python-ideas] Allowing def to assign to anything

Chris Angelico rosuav at gmail.com
Mon Oct 26 02:20:37 EDT 2015


On Mon, Oct 26, 2015 at 5:02 PM, Alexander Walters
<tritium-list at sdamon.com> wrote:
> If `def` is allowed to assign to anything (anything that is legal at the
> left hand side of an = in that scope), annoying artifacts go away.  The
> syntax I propose should be backwards compatible.
>
> ```
> dispatch = {}
>
> def dispatch['foo'](bar):
>     return bar * bar
> ```
>
> Does this make anything possible that is impossible now?  No.  But it does
> make the intent of the module author clear - the function is only ever
> intended to live inside that dict, or list, or other structure.  This, to
> me, is less annoying to write, and is more readable.  This obviously could
> be used outside of creating dispatch dictionaries, but that is the use case
> I would benefit from.

I agree; the idea has been raised a few times, and I think it'd be
helpful. It's probably not necessary to allow the _entire_ scope of
"anything legal on the left of =", as that's pretty broad; even if the
only form allowed were obj[key], it'd be useful.

But for building a dispatch dictionary, you could simply decorate your
functions with a capturer:

dispatch = {}

def cmd(func):
    dispatch[func.__name__] = func
    return func

@cmd
def foo(bar):
    return bar * bar

You can even merge the decorator and the dict itself:

class DispatchDict(dict):
    def __call__(self, func):
        self[func.__name__] = func
        return func

dispatch = DispatchDict()

@dispatch
def foo(bar):
    return bar * bar

This does require that your dict keys be legal identifiers (you can't
do "def dispatch['!'](x):" as "@cmd def !(x)"), but for a lot of
common cases, this does work. I've used this style for building
argparse UIs and such, and it's a lot easier than most other options
I've played with.

ChrisA


More information about the Python-ideas mailing list