Nested function scope problem
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Fri Jul 28 03:07:20 EDT 2006
Gerhard Fiedler a écrit :
> On 2006-07-27 17:10:55, Bruno Desthuilliers wrote:
>
>
>>>Isn't being on the LHS the only way to write to a non-mutable object?
>>
>>You *don't* "write to a non-mutable object". You rebind the name to
>>another object (mutable or not, that's not the problem).
>
>
> Ok, sloppy writing (sloppy thinking, or probably incomplete understanding
> :) on my part. Let me rephrase the three original questions:
>
>
>>>Isn't being on the LHS the only way to write to a non-mutable object? Are
>>>there situations where binding happens without writing to a variable? Are
>>>there write accesses to non-mutable objects where the name is not on the
>>>LHS?
>
>
> Rephrased as:
>
> Isn't being on the LHS (of an assignment) the only way to (re)bind a
> variable?
<pedantic>
s/variable/name/
</pedantic>
> Are there situations where binding happens without an explicit
> assignment with the variable name being on the LHS?
Assignment aside, binding occurs:
1/ on evaluation of import, class and def statement
see Dennis answer for an example with import. Here are examples with def
and class:
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'a' is not defined
>>> a = []
>>> a
[]
>>> id(a)
1078043820
>>> def a(): pass
...
>>> a
<function a at 0x404162cc>
>>> id(a)
1078026956
>>> class a: pass
...
>>> a
<class __main__.a at 0x4040dadc>
>>> id(a)
1077992156
>>>
2/ on function call for the function's arguments
This second case won't obviously *re*bind existing names in the
function's namespace, nor in the caller namespace, so we don't care here.
3/ as a result of a list comp or for loop:
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'a' is not defined
>>> for a in range(3): pass
...
>>> a
2
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'b' is not defined
>>> [b for b in range(3)]
[0, 1, 2]
>>> b
2
>>>
AFAICT and IIRC, this should cover most cases - please someone correct
me if I forgot something here...
> Can the object
> referenced by a variable name get changed without the variable name
> appearing on the LHS?
>>> a = []
>>> id(a)
1078043820
>>> def change(l):
... l.append(42)
...
>>> change(a)
>>> a
[42]
>>> id(a)
1078043820
>>>
First assignment aside, the *name* 'a' is never on the LHS of an
assignment, yet the object referenced by name 'a' got 'changed' : it was
initially empty, after call to change() it contains an int.
Yes, I know, this is not what you meant (and no, name 'a' has not been
rebound) - but that's really what you asked : the object referenced by
name 'a' got changed without name 'a' being on the LHS !-) Hence the
emphasis on the difference between mutating (modifying/changing/...) an
object and rebinding a name...
I think your intented question was more like : "can a name be rebound
without that name being on the LHS of an assignment", and it's addressed
above
> (I hope I got this right now...
Almost !-)
> asking the correct questions is not so easy
> sometimes :)
Indeed !-)
More information about the Python-list
mailing list