Hi Nick, > messing about with classes I've come across something basic that I don't > understand.
Your issue is not so much with classes as it is with namespaces. You'll hit the exact same problem with simple functions. > Take this class > > class T: > def p(self): > print x In this case, the Python reference states that if a name (x) is not found in a block (i.e. inside the p method), it will look in its surrounding scope for it. That would be the global namespace. Given the fact that you defined x as a global variable, it finds it there and it works as expected. > Now this > class T: > def p(self): > x += 1 > print x > This outputs > UnboundLocalError: local variable 'x' referenced before assignment Here is what the Python docs have to say about assignment: If the target is an identifier (name): If the name does not occur in a global statement in the current code block: the name is bound to the object in the current local namespace. In other words, when trying to assign a new value to x, it: 1. looks if x was defined as global *inside the current function/class* 2. sees that it was not defined as global -> therefore it must be local 3. tries to get the value of that local x 4. finds there is no local x -> raises exception > So I tried this > > class T: > def p(self): > x += 1 > print x > > if __name__ == '__main__': > global x > x = 1 > t = T() > t.p() > but that gives me the same UnboundLocalError exception. This second attempt is almost but not quite right: the global statement is in the wrong place. x is by definition global if defined outside a class or function, so adding "global" in front of it won't make a difference. The point is that if you try to assign a value to a global variable inside a function or class definition, you must tell Python *in that block* that you want to assign to a global variable, not a local one. >>> def p(): ... global x ... x += 1 >>> x = 5 >>> p() >>> x 6 Similar problems can occur when defining a function inside another function: >>> def a(): ... aa = 2 ... def b(): ... print aa # aa in surrounding namespace, not local to b() ... b() >>> a() 2 >>> def a(): ... aa = 2 ... def b(): ... aa += 1 # in surrounding namespace, not local to b() ... print aa ... b() >>> a() UnboundLocalError: local variable 'aa' referenced before assignment > No doubt the answer is staring me in the face ... but I still can't see it. I would recommend against using global variables this way (modifying them inside functions). It's better to use method parameters for input and the return statement to output any necessary modifications, e.g.: def p(inp): output = inp + 1 print output return output if __name__ == '__main__': x = 5 x = p(x) It would be even better with a decent function name of course :). More info available in paragraph 4.1 of the Python reference manual. -- Yours, Andrei ===== Mail address in header catches spam. Real contact info: ''.join([''.join(s) for s in zip( "[EMAIL PROTECTED] pmfe!Pes ontuei ulcpss edtels,s hr' one oC.", "rjc5wndon.Sa-re laed o s npbi ot.Ira h it oteesn edt C")]) _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor