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