Нудний вступ я опущу, і перейду зразу до розваги:
def case(func): # декоратор прикладу print func.__name__ # печатаємо назву try: func() # виконуємо функцію except Exception, e: # Якщо є помилки print 'Error:', e # помічаємо і продовжуємо print @case def test_a(): x = 1 def inner(): x = 2 # x в цій області імен посилається на новий об’єкт - 2 print 'inner:', x # x == 2 inner() print 'outer:', x # x == 1. Цю область імен ми не чіпали @case def test_b(): x = [1] def inner(): x[0] = 2 # при обчисленні x[0], ми шукаємо x у всіх просторах тут і вище print 'inner:', x # x == [2], x посилається на все той же об’єкт, але він змінився inner() print 'outer:', x # x == [2], сказано ж, об’єкт змінився. @case def test_c(): x = 1 def inner(): x +=1 # генерує UnboundLocalError # бо x - в лівій частині присвоєння, що робить його локальним. # а в правій частині - x + 1, значення якого ще не визначено # бо ж x щойно з’явився в просторі імен # детальніше про те чому так: http://eli.thegreenplace.net/2011/05/15/understanding-unboundlocalerror-in-python/ print 'inner:', x inner() print 'outer:', x # сюди ми не доходимо # Як реалізувати нелокальну змінну, якщо ви працюємо не з третім Python? @case def test_d(): # використати mutable об’єкт nonlocal = lambda:7 # функція підходить nonlocal.x = 1 def inner(): nonlocal.x += 1 print 'inner:', nonlocal.x # == 2 inner() print 'outer:', nonlocal.x # == 2
Мораль теж опущу, все таки потрібно працювати.
Filed under: Кодерство Tagged: Python