[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