syntax for code blocks

Kiuhnm kiuhnm03.4t.yahoo.it
Wed May 2 06:52:50 EDT 2012


On 5/2/2012 4:43, alex23 wrote:
> [Apologies in advance if this comes through twice]
>
> On May 2, 12:18 am, Kiuhnm<kiuhnm03.4t.yahoo.it>  wrote:
>> "Most Pythonic" doesn't mean better, unfortunately.
>
> Nor does it mean "Kiuhnm prefers it".

That goes without saying.

>> 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
>>
>> def when_prime(n):
>>       pass
>>
>> def before_check():
>>       pass
>>
>> def after_check():
>>       pass
>>
>> func(some_args, {'when_odd' : when_odd,
>>                    'when_prime' : when_prime,
>>                    'before_check' : before_check,
>>                    'after_check' : after_check})
>
> When would you _ever_ define a function like this? Why are you passing
> in _named_ callbacks? Are you calling them by name? Then declare them
> in the function signature and rely on scoping. Does func() branch on
> existent keys? Then don't write code like that.
>
> At the very _least_, you could change the function call to:
>
>      func(some_args, locals())

I think that's very bad. It wouldn't be safe either. What about name 
clashing and how would you pass only some selected functions?
A second call would also need some cleaning up leading to some serious bugs.

> But as you're _passing them in by name_ why not just make it
> func(some_args) and pick them up out of the scope.

Because that's not clean and maintainable. It's not different from using 
global variables.

> _No one_ writes Python code like this. Presenting bad code as
> "pythonic" is a bit of a straw man.

How can I present good code where there's no good way of doing that 
without my module or something equivalent?
That was my point.

>> My way
>> ------
>>
>> with func(some_args)<<  ':dict':
>>       with when_odd as 'n':
>>           pass
>>       with when_prime as 'n':
>>           pass
>>       with before_check as '':
>>           pass
>>       with after_check as '':
>>           pass
>
> This is unintuitive, to say the least. You're effectively replacing
> the common form of function definition with "with when_odd as 'n'",
> then using the surrounding context manager to limit the scope.

What's so unintuitive about it? It's just "different".

> More importantly, _you're naming your "anonymous" code blocks_, I'm
> guessing so that func() can choose which ones to use. But if you're
> naming them, why not just use a function?

I'm creating a dictionary, not naming my blocks just for the sake of it.
If you use a function, you end up with the solution that you called 
'bad' and non-pythonic.

> I'm not entirely sure what your 'solution' offers over something like:
>
> class FOO(object):
>      def __init__(self, fn):
>          self.fn = fn
>
>      def __enter__(self):
>          return self.fn
>
>      def __exit__(self, exc_type, exc_value, traceback):
>          pass
>
> def func(x, before_check=None, after_check=None, when_odd=None,
> when_prime=None):
>      pass
>
> with FOO(func) as f:
>      def before_check(x):
>          pass
>      def after_check(x):
>          pass
>      def when_odd(x):
>          pass
>      def when_prime(x):
>          pass
>
>      f(1)

The problem is always the same. Those functions are defined at the 
module level so name clashing and many other problems are possible.

I remember a post on this ng when one would create a list of commands 
and then use that list as a switch table. My module let you do that very 
easily. The syntax is:

     with func() << ':list':
         with 'arg':
             cmd_code
         with 'arg':
             cmd_code
         with '':
             cmd_code

Kiuhnm



More information about the Python-list mailing list