On Fri, 18 Mar 2005 09:16:42 -0800, Jeff Shannon <[EMAIL PROTECTED]> wrote:
>Antoon Pardon wrote: >> Op 2005-03-16, Jeff Shannon schreef <[EMAIL PROTECTED]>: >> >>>Bruno Desthuilliers wrote: >>> >>>>- if x is a class attribute of class A and a is an instance of A, >>>>a.x=anyvalue create a new instance attribute x instead of modifying A.x >>> >>>This is very consistent with the way that binding a name in any scope >>>will shadow any bindings of that name in "higher" scopes. It is the >>>same principle by which one is able to use the same name for a >>>function-local variable that is used for a global variable, without >>>destroying that global variable. [...] >> >> Not entirely. The equivallent is imposible in function scope. >> If function scope would work exactly equivallent as the >> above the following should work >> >> a = 42 >> def f(): >> a = a + 1 >> print a f() # ;-) >> print a >> >> And the result should be: >> >> 43 >> 42 >> IIRC, in some past version that used to be the way it worked (if you don't forget to call f() ;-) I think it is logical. I.e., the right hand side of a = a + 1 is logically evaluated first, so the status at that time should IMO determine the meaning of "a" -- i.e., look for it in an outer scope. Next comes the local assignment of "a" which should create a local name binding, but the code for determining the assigned value should IMO be the code for the "a + 1" with no local binding of "a" yet existing. I don't know how much code would break to go back to that, but maybe not so much, since it's not legal now: >>> a = 42 >>> def f(): ... a = a +1 ... print a ... >>> f() Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 2, in f UnboundLocalError: local variable 'a' referenced before assignment >>> print a 42 BTW, I would like a re-assign or find-and-rebind operation spelled ":=" which would make x := 123 mean look for x as if to read its value in a right hand side expression, (except do not look into __builtins__) and wherever found, rebind to 123 -- and if not found, raise an exception. I think var := 'something' would be a useful substitute for the idiom of var[0] = 'something' and be unambiguous. ":=" as an operator could combine like <op>= if desired, so we could write var +:= some.long.expression[that].you('do')**not.want.to.type.twice instead of _ = some.long.expression[that].you('do')**not.want.to.type.twice var +:= _ # meaning var := var + _ or such. > >I'd still say that the name binding rules are very consistent. The They are consistent, but I have to say the function-body full lookahead to determine local vs outer (not to mention normal function vs generator) jars my sensibilities. >name lookup rules are a little different (as they *should* be for >class/instance attributes), and that's why there's a different net >effect (UnboundLocalError) as shown in your example. I'd say, >however, that if there's a special case here it's with the >function-local variables, not the class/instance attributes. It's the >optimizations to the function-local namespace which prevent >transparent re-binding of global names. And given that the >function-local namespace is by far the most heavily used, and the >relative utility (and wisdom) of using globals in this way, this is a >case where the benefit of the special case is well worth the cost of >its slight inconsistency. The optimization argument goes away with x := something I think, since the x search can be limited to looking in the lexical environment exactly like looking for read-only outer scope names now, just with different consequences for finding or not finding. Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list