Корректность в области видимости переменной - PullRequest
7 голосов
/ 02 марта 2010

В настоящее время я разрабатываю некоторые вещи на Python, и у меня есть вопрос о области видимости переменных.

Это код:

a = None
anything = False
if anything:
    a = 1
else:
    a = 2

print a # prints 2

Если я удаляю первую строку (a = None), код все равно работает как прежде. Однако в этом случае я бы объявил переменную внутри блока «если», а в отношении других языков, таких как Java, эта переменная была бы видна только внутри «если».

Как работает переменная область видимости в Python и каков хороший способ программирования в подобных случаях?

Спасибо!

Ответы [ 5 ]

8 голосов
/ 02 марта 2010

Как правило, области видимости создаются в трех местах:

  1. Область видимости файла - иначе называется областью модуля
  2. Class-scope - создается внутри class блоков
  3. Function-scope - создается внутри def блоков

(Есть несколько исключений из них.)

Присвоение имени резервирует его в пространстве имен области, помеченном как несвязанное до достижения первого назначения. Таким образом, для ментальной модели вы назначаете значения именам в области.

2 голосов
/ 02 марта 2010

Я считаю, что Python использует область действия для локальных переменных. То есть, в любой данной функции, если вы присваиваете значение локальной переменной, оно будет доступно с этого момента внутри этой функции, пока не вернется. Следовательно, поскольку обе ветви вашего кода гарантированно присваиваются a, нет необходимости изначально присваивать None a.

Обратите внимание, что когда вы также можете получить доступ к переменным, объявленным во внешних функциях - другими словами, в Python есть замыкания.

def adder(first):
    def add(second):
        return first + second

    return add

Это определяет функцию под названием сумматор. При вызове с аргументом first он возвращает функцию, которая добавляет любой аргумент, который он получает, к first и возвращает это значение. Например:

add_two = adder(2)
add_three = adder(3)
add_two(4) # = 6
add_three(4) # = 7

Однако, хотя вы можете прочитать значение из внешней функции, вы не можете его изменить (в отличие от многих других языков). Например, представьте, что вы пытаетесь реализовать аккумулятор. Вы можете написать код так:

def accumulator():
    total = 0
    def add(number):
        total += number
        return total
    return add

К сожалению, попытка использовать этот код приводит к сообщению об ошибке:

UnboundLocalError: local variable 'total' referenced before assignment

Это потому, что строка total += number пытается изменить значение total, чего нельзя сделать в Python таким образом.

1 голос
/ 02 марта 2010

Нет проблем с назначением переменной в блоке if.

В этом случае он присваивается обеим ветвям, поэтому вы можете видеть, что он определенно будет определен, когда вы придете его напечатать.

Если одна из ветвей не присваивается a, то возникает исключение NameError, когда вы пытаетесь распечатать его после этой ветви

0 голосов
/ 02 марта 2010

Я начинающий программист, но, насколько я знаю, в Python частные переменные не существуют. подробное обсуждение смотрите в личных переменных в документации по python.

полезную информацию также можно найти в разделе "Области и пространства имен" на той же странице.

лично я пишу код, подобный тому, который вы публиковали почти каждый день, особенно когда условие зависит от получения ввода от пользователя, например

if len(sys.argv)==2:
    f = open(sys.argv[1], 'r')
else:
    print ('provide input file')

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

надеюсь, это поможет.

0 голосов
/ 02 марта 2010

Python не требует, чтобы переменные были объявлены изначально, поэтому вы можете объявлять и определять в произвольных точках.И да, область действия - это область действия функции, поэтому она будет видна за пределами if.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...