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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to