On Mon, 23 Feb 2009 00:06:58 -0800, neoedmund wrote: > see the 3 small piece of code, i cannot understand why it result as > this. > > 1. > def test(): > abc="111" > def m1(): > print(abc) > m1() > test() > > Output: 111
abc is local to test(). print(abc) looks for a local abc, can't find one, and so searches the higher scope, and finds it there. > 2. > def test(): > abc="111" > def m1(): > print(abc) > abc+="222" > m1() > test() > > Output: > print(abc) > UnboundLocalError: local variable 'abc' referenced before assignment Because you make an assignment to abc inside the m1() function, but didn't declare it as global, Python assumes that it must be a local variable. So when you try to print it, it doesn't have a value yet. Solution: don't do that, or use the statement nonlocal (like global, except I think it is only introduced in Python 3.0). > 3. > def test2(): > abc=[111] > def m1(): > print(abc) > abc.append(222) > m1() > print(abc) > test2() > > Output: > [111] > [111,222] > > it seems "you cannot change the outter scope values but can use it > readonly." But you're not using it read-only, because the append worked. What you can't do is assign to the name. Have a look at the disassembled code: >>> import dis >>> def spam(): ... print x ... y = x+1 ... >>> dis.dis(spam) 2 0 LOAD_GLOBAL 0 (x) 3 PRINT_ITEM 4 PRINT_NEWLINE 3 5 LOAD_GLOBAL 0 (x) 8 LOAD_CONST 1 (1) 11 BINARY_ADD 12 STORE_FAST 0 (y) 15 LOAD_CONST 0 (None) 18 RETURN_VALUE >>> >>> def ham(): ... print x ... x = x+1 ... >>> dis.dis(ham) 2 0 LOAD_FAST 0 (x) 3 PRINT_ITEM 4 PRINT_NEWLINE 3 5 LOAD_FAST 0 (x) 8 LOAD_CONST 1 (1) 11 BINARY_ADD 12 STORE_FAST 0 (x) 15 LOAD_CONST 0 (None) 18 RETURN_VALUE -- Steven -- http://mail.python.org/mailman/listinfo/python-list