Подтвердить что ты не робот

Python: Как я могу захватить переменную, объявленную в не глобальном внешнем пространстве?

Дано:

def f():
    x = 0
    def g():
        h()
    def h():
        x += 1
        print(x)
    g()

>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in f
  File "<stdin>", line 4, in g
  File "<stdin>", line 6, in h
UnboundLocalError: local variable 'x' referenced before assignment
>>>

Как я могу сделать h см. переменную x?

Спасибо.

ИЗМЕНИТЬ

Должен был упомянуть об этом раньше, я использую Python 2.7.3

4b9b3361

Ответ 1

Вы можете сделать x a атрибут функции:

def f():
    f.x = 0
    def g():
        h()
    def h():
        f.x += 1
        print(f.x)
    g()

Кроме того, с Python 3 вы можете использовать nonlocal ключевое слово.

Ответ 2

Если вы используете Python 3, вы используете ключевое слово nonlocal. Поместите nonlocal x в начало функции h. Если вы используете Python 2.x, обходной путь делает x список с одним элементом, поэтому вы можете его изменить:

def f():
    x = [0]
    def g():
        h()
    def h():
        x[0] += 1
        print x[0]
    g()

f()

Ответ 3

В Python 3 просто используйте nonlocal:

def f():
    x = 0
    def g():
        h()
    def h():
        nonlocal x
        x += 1
        print(x)
    g()
f()

Ответ 4

Не можем ли мы поставить x в качестве аргументов функции в качестве обходного пути

def f():
    x = 0
    def g():
        h(x)
    def h(x):
        x += 1
        print(x)
    g()

f() 

Ответ 5

Проще всего использовать класс dict или пустой, например:

class Empty:
    x = 0

def f():
    closure1 = dict(x=0)
    closure2 = Empty()
    def g(): h(x)
    def h(x):
        closure1["x"] += 1
        closure2.x += 1
    g()
    print closure1["x"], closure2.x

Хотя многие хорошие решения уже были предоставлены, у них есть угловые случаи:

  • нелокальный, для Ashwini, только Python 3.x
  • атрибут функции, за ovgolovin, потерпит неудачу, будет f переопределен и позже вызван ссылкой