[Python-ideas] Allowing def to assign to anything
Steven D'Aprano
steve at pearwood.info
Mon Oct 26 09:45:39 EDT 2015
On Mon, Oct 26, 2015 at 02:02:00AM -0400, Alexander Walters wrote:
> In my code, I write a lot of dispatch dictionaries (for lack of a switch
> statement, but I will not hold my breath for that). In trying to make
> writing these dictionaries less annoying, I tend to use many lambdas. I
> can let you guess at what problems that has resulted in. Of course, the
> preferred way to write such dictionaries is by using a regular function,
> and adding that function to a dictionary. This isn't exactly a problem
> - it works, and works well, but it is annoying to write, and leaves
> artifacts of those functions in module scope. I propose a little bit of
> sugar to make this a little less annoying.
In this case, leaving "artifacts" in the module scope is a feature. If
your function is simple enough to express in a simple expression, then a
lambda may be the right solution. But if it requires a full block, then
chances are that it's too complex for it to be obviously correct, which
means you should test it. Giving the function a name and module scope
supports testing.
But if you really want to get rid of it:
del the_function
after adding it to the dispatch table.
Or, stick them in their own namespace. For a package, that might mean
moving the dispatch table and its associated functions into its own
module. Or, put them in a class:
class Switch:
def cheese(x):
...
def spam(x):
...
def eggs(x):
...
dispatch = {}
dispatch.update(Switch.__dict__)
result = dispatch[key](arg)
Or one could write a class decorator (or a metaclass) to post-process
the class and returns whatever you like. If I were doing this a lot, I
would invest the time in building a nice switch construct, before
looking for new syntax.
> 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.
Assign to *anything*?
a, b, c = 1, 2, 3
def a, b, c(x, y):
...
I don't see that, at least, working.
> ```
> 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.
It's not clear to me. To me, it looks like you've badly mistyped a
function annotation. If you hadn't explained what you wanted, I wouldn't
have a clue what "def dispatch['foo'](bar)" meant.
--
Steve
More information about the Python-ideas
mailing list