syntax for code blocks

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue May 1 11:11:03 EDT 2012


On Tue, 01 May 2012 16:18:03 +0200, Kiuhnm wrote:

> "Most Pythonic" doesn't mean better, unfortunately.

Perhaps. But this example is not one of those cases.


> For instance, assume that you want to write a function that accepts a
> dictionary of callbacks:
>    func(some_args, callbacks)
> 
> Pythonic way
> ------------
> 
> def when_odd(n):
>      pass
[snip multiple function definitions]

> func(some_args, {'when_odd' : when_odd,
>                   'when_prime' : when_prime,
>                   'before_check' : before_check,
>                   'after_check' : after_check})

> My way
> ------
> 
> with func(some_args) << ':dict':
>      with when_odd as 'n':
>          pass
>      with when_prime as 'n':
>          pass


If you actually try that, you will see that it cannot work. You get:

SyntaxError: can't assign to literal


Have you actually tried to use these code blocks of yours? I asked you 
for a *working* example earlier, and you replied with examples that 
failed with multiple NameErrors and no hint as to how to fix them. And 
now you give an example that fails with SyntaxError. I'm reluctantly 
coming to the conclusion that these "code blocks" of yours simply do not 
work.


>      with before_check as '':
>          pass
>      with after_check as '':
>          pass

You have a bug in one or more of those callbacks.

Of course you do -- all non-trivial software has bugs. The question is, 
how are you going to find it? You can't unit-test the individual 
callbacks, because they don't exist in a form that can be tested.

So in this case, even though Python is slightly more verbose, and forces 
you to have the discipline of writing named functions ahead of time, this 
is actually a *good* thing because it encourages you to test them.

If the callbacks are trivial functions, the Pythonic way is to use 
lambdas:

func(some_args, {'when_odd': lambda n: n-1,
                 'when_prime': lambda n: n**2 - 1, 
                 ...})

although I would discourage that unless they are *really* trivial. But 
for callbacks of any complexity, they will need to be tested, otherwise 
how do you know they do what you want them to do?

Your code blocks make unit testing of the callbacks impossible, and for 
that reason the Pythonic way is better.


-- 
Steven



More information about the Python-list mailing list