Paddy a écrit : > Bruno Desthuilliers wrote: > >>Frank Millman a écrit : >> >>>Paddy wrote: >>> >>> >>>>Hi, >>>>I am trying to work out why I get UnboundLocalError when accessing an >>>>int from a function where the int is at the global scope, without >>>>explicitly declaring it as global but not when accessing a list in >>>>similar circumstances. >>>> >>> >>> >>>There has just been a long thread about this. I think I understand it >>>now. Here is my explanation. >>> >>>Ignoring nested scopes for this exercise, references to objects (i.e. >>>variable names) can exist in the local namespace or the global >>>namespace. Python looks in the local namespace first, and if not found >>>looks in the global namespace. >>> >>>Any name assigned to within the function is automatically deemed to >>>exist in the local namespace, unless overridden with the global >>>statement. >> >>And this even of the local bindings sequentially comes after another >>access to the name, ie: >> >>g = 0 >> >>def fun(): >> x = g # UnboundLocalError here >> g += 1 >> return x >> >> >>>With the statement 'm = m + 1', as m is assigned to on the LHS, it is >>>deemed to be local, but as m does not yet have a value on the RHS, you >>>get Unbound Local Error. >> >>Right >> >> >>>With the statement 'n[0] = n[0] + 1', n is not being assigned to, >> >>Right >> >> >>> as it >>>is mutable. >> >>n is effectively mutable, but this is totally irrelevant. In your >>snippet, n is not 'assigned to', it's "mutated" (ie a state-modifying >>method is called). The snippet: >> >>n[0] = n[0] + 1 >> >>is syntactic sugar for >> >>n.__setitem__(0, n.__getitem__(0) + 1) >> >>IOW, it's just method calls on n. > > > So, > An assignment statement may assign an object to a name,
An assignment statement binds an object to a name. > in which case > the name is 'tagged' as being local, Unless that names has been declared as global or lives in another namespace (ie is an element of a mutable collection or an attribute of another object). > An assignment statement may mutate a mutable object already bound to a > name, in which case the assignment will not 'tag' the name as being > local. consider this code: class Foo(object): def __init__(self, baaz): self.baaz = baaz def bar(foo, bak): foo.baaz = bak Which name is getting rebound here ? foo, or foo.baaz ? > I guess Bruno, you mean irrelevant as in 'although only mutable objects > can have their state modified; if n has a mutable value but the > assignment statement changed the object referred to by n, then the name > would be tagged as local'? Unless the name has been declared as global, yes. -- http://mail.python.org/mailman/listinfo/python-list