[Python-il] [pyweb-il:1072] Python coding question

Shai Berger shai at platonix.com
Fri Jul 9 02:49:49 IDT 2010


On Thursday 08 July 2010, you wrote:
> > I wouldn't like the trade-off where you "win" a couple of
> > questions on mailing-lists and pay for it with the DRY in
> > 
> > complex_or_just_long_reference = complex_or_just_long_reference + 1
> 
> But wouldn't you prefer something like
>   complex_or_just_long_reference = same + 1
> which turns out to be more powerful than the standard pack of syntactic
> sugar constructs:
>   complex_or_just_long_reference = max(same, new_thing)
> or
>   complex_or_just_long_reference = "(" + same + ")"
> IMHO, this is more readable and saves most of the mess with long names.
> 

This is an interesting idea -- I agree that it has merits, but I also see why 
it wouldn't be included in a language where 'self' is a convention and not a 
keyword.

While it is definitely more general, I don't see it as more readable in the 
common cases. Between C and its descendents, += has become quite entrenched.

> We have created a list of functions, each supposedly defined over a
> 
> > different
> > value of i. Each is a separate object, because in principle the closures
> > are
> > different. If i were really nothing but a name that gets re-bound in
> > every loop iteration, we would expect, for any j in 0..4, to have
> > funcs[j]()==j...
> > 
> > >>> funcs[1]()
> > 
> > 4
> > 
> > ...but in fact, they all return the last value; the closure references a
> > variable, not a name.
> 
> Cannot see how what you say here contradicts the explanation on the Wiki.
> This only shows that the resolution of the name "i" happens on function
> execution rather than on function definition, which is the expected
> behavior for agile languages.

Indeed, the example I gave was not exactly supporting my claim. It did show a 
place where a name behaves like a variable reference, but as you correctly 
argue, the behavior can be explained by late binding.

However, if that were the whole story, this code would raise a NameError:

>>> def f():
...     i=5
...     def g(): return i
...     del i
...     return g
... 
>>> f()()

In fact, the deletion of i in f is a syntax error, complaining about deletion 
of a variable. This is done because "If a name binding operation occurs 
anywhere within a code block, all uses of the name within the block are 
treated as references to the current block" 
(http://docs.python.org/reference/executionmodel.html) -- that is, while the 
exact object bound to the name is looked up as late as possible, the scope of 
the name is set already at function definition (compilation) time. 

Thus, the nested function will only look for the current binding of i in the 
local namespace of its containing function; IMHO, this qualifies as a true 
variable (though, true, it is not a constant place in memory).

I hope this is still interesting to people here,

	Shai.


More information about the Python-il mailing list