On 13/06/2011 15:33, Steven D'Aprano wrote:
Nick Coghlan wrote:
On Mon, Jun 13, 2011 at 5:11 PM, Steven D'Aprano <st...@pearwood.info>
wrote:
Function parameters should be kept for actual arguments, not for
optimizing
name look-ups.
Still, the post-** shared state (Jan's option 2) is likely the most
obvious way to get early binding for *any* purpose without polluting
the externally visible parameter list.
I wouldn't call adding even more complexity to function signatures
"obvious", although I grant that it depends on whether you're Dutch :)
Another disadvantage is that it uses a symbol instead of a word. Too
many symbols, and your code looks like Perl (or APL). It's hard to
google for ** to find out what it means. It's harder to talk about a
symbol than a word. (In written text you can just write ** but in speech
you have to use circumlocutions or made-up names like double-splat.)
[...]
It seems like the path of least resistance to me - the prevalence of
the default argument hack means there's an existing, widespread
practice that solves real programming issues, but is flawed in some
ways (specifically, messing with the function's signature). Allowing
declarations of shared state after the keyword-only arguments seems
like a fairly obvious answer.
The problem with injecting locals in the parameter list is that it can
only happen at write-time. That's useful, but there's a major
opportunity being missed: to be able to inject at runtime. You could add
test mocks, optimized functions, logging, turn global variables into
local constants, and probably things I've never thought of.
Here's one use-case to give a flavour of what I have in mind: if you're
writing Unix-like scripts, one piece of useful functionality is "verbose
mode". Here's one way of doing so:
def do_work(args, verbose=False):
if verbose:
pr = print
else:
pr = lambda *args: None
pr("doing spam")
spam()
pr("doing ham")
ham()
# and so on
if __name__ == '__main__':
verbose = '--verbose' in sys.argv
do_work(my_arguments, verbose)
[snip]
Here's another way:
def do_work(args):
do_work.pr("doing spam")
spam()
do_work.pr("doing ham")
ham()
# and so on
if __name__ == '__main__':
verbose = '--verbose' in sys.argv
if '--verbose' in sys.argv:
do_work.pr = print
else:
do_work.pr = lambda func: func # do nothing
do_work(my_arguments)
--
http://mail.python.org/mailman/listinfo/python-list