syntax for code blocks
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu May 3 23:47:36 EDT 2012
On Thu, 03 May 2012 19:44:57 -0700, alex23 wrote:
[snip]
> My version was:
>
> def a(): pass
> def b(): pass
>
> func_packet = locals()
> func(arg, func_packet)
>
> Now, please explain how that produces name-clashes that your version
> does not.
I too am uncomfortable about passing locals() to a function, but not
because of imaginary "name clashes". The problem as I see it is that this
will give the function access to things the function has no need for.
While CPython doesn't allow the called function to rebind names in the
local scope (except in the case where the local scope is also the global
scope), that may not apply to all Python implementations. So code which
works safely in CPython may break badly in some other implementation.
Another problem is that even in implementations where you can't rebind
locals, the called function might mutate them instead. If any of the
content of locals() are mutable, you're giving the function the potential
to mutate them, whether it needs that power or not.
Let me put it this way... suppose you had a function with a signature
like this:
def spam(a, b, c, **kwargs):
...
and you knew that spam() ignores keyword arguments that it doesn't need.
Or at least is supposed to. Suppose you needed to make this call:
spam(23, 42, ham=None, cheese="something")
Would you do this instead?
foo = ['some', 'list', 'of', 'things']
spam(23, 42, ham=None, cheese="something", aardvark=foo)
on the basis that since aardvark will be ignored, it is perfectly safe to
do so?
No, of course not, that would be stupid. Perhaps spam() has a bug that
will mutate the list even though it shouldn't touch it. More importantly,
you cause difficulty to the reader, who wonders why you are passing this
unused and unnecessary aardvark argument to the function.
My argument is that this is equivalent to passing locals() as argument.
Your local scope contains some arbitrary number of name bindings. Only
some of them are actually used. Why pass all (say) 25 of them if the
function only needs access to (say) three? To me, passing locals() as an
argument in this fashion is a code-smell: not necessary wrong or bad, but
a hint that something unusual and slightly worrying is going on, and you
should take a close look at it because there *may* be a problem.
> So far, pretty much everyone who has tried to engage you on this subject
> on the list. I'm sorry we're not all ZOMGRUBYBLOCKS!!!!111 like the
> commenters on your project page.
Goddamit, did I miss a post somewhere? What the hell is this project
people keep talking about?
--
Steven
More information about the Python-list
mailing list