Почему подфункция не наследует область видимости в Python? - PullRequest
5 голосов
/ 25 апреля 2011

Я не понимаю, почему не работает следующее:

def foo( x ):
    n = 1
    summe = 0
    def bar():
        n -= 1
    for i in range(0,10):
        y = x+i+n
        x += i
        summe += y
        print "{0} = {1} + {2} + {3}".format(y,x,i,n)
        bar()
    print "summe =", summe
    return summe

Почему bar() не наследует область действия foo()?Это C'ism, который мне нужно забыть?Есть ли способ, которым я могу заставить эту работу?

Ответы [ 2 ]

15 голосов
/ 25 апреля 2011

PEP 3104 содержит объяснение и решение этой проблемы.Проблема заключается в том, что Python рассматривает любое присвоение имени как объявление переменной local .

>>> n = 1
>>> def bar():
>>>     n = n + 1
>>> 
>>> bar()
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    bar()
  File "<pyshell#7>", line 2, in bar
    n = n + 1
UnboundLocalError: local variable 'n' referenced before assignment

Существует несколько способов решения этой проблемы, если вы используете версию Python без нелокальное ключевое слово.Один уродливый трюк - это обернуть вашу переменную в список:

>>> n=[1]
>>> def bar():
>>>     n[0] = n[0] + 1
>>> 
>>> bar()
>>> n
[2]

Хотя этот трюк работает, обычно лучше переписать код, чтобы устранить необходимость в нелокальных присваиваниях.

1 голос
/ 17 августа 2014

Я действительно нашел этот вопрос, когда искал решение немного другой проблемы. Локальные переменные не наследуются от sub, но ничто не мешает вам передать переменную во внутреннюю функцию и затем присвоить результаты при возврате.

Это дополнение к оператору nonlocal в PEP 3104 . Это немного менее уродливо и делает запоминание еще одного ключевого слова python менее важным.

def foo( x ):
    n = 1
    summe = 0
    def bar(n):
        n -= 1
        return n
    for i in range(0,10):
        n = bar(n)
        y = x+i+n
        x += i
        summe += y
        print "{0} = {1} + {2} + {3}".format(y,x,i,n)
    print "summe =", summe
    return summe
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...