Проблема с областью видимости переменной Python - PullRequest
0 голосов
/ 21 сентября 2011

Сценарий Python:

def show(name):
    def getName():
        return _name
    def setName(value):
        _name = value
    _name = ''
    print('Input parameter: ', name)
    print('Global variable: ', say_hello)
    print('Change private variable: ', setName(name))
    print('Get private variable: ', getName())
    print('Private variable: ', _name)
    print('Input parameter: ', name)
say_hello = 'hello'
show('Jim')

Вывод:

Input parameter: Jim
Global variable: hello Change
private variable: None
Get private variable:
Private variable:
Input parameter: Jim 

Почему внутренняя функция не меняет значение _name, но функция show может получить значение say_hello?Я знаю, что это проблема переменной области, но я хочу знать некоторые детали.

Ответы [ 3 ]

1 голос
/ 21 сентября 2011

Назначения в функциях назначаются в области действия функций.setName присваивает _name в локальной области действия в setName, внешний _name не затрагивается.

В Python 2.X можно назначить модулю глобальную область видимости, используя глобальнуюоператор, но не во внешнюю локальную область.

Python 3.X добавляет оператор nonlocal (подробности см. в PEP-3104, если вы заинтересованы).В вашем примере, нелокальный можно использовать в setName для назначения внешней локальной области.

В этом посте обсуждается область видимости переменных в Python с некоторыми хорошими примерами и обходными путями (см. Пример 5 специально).

0 голосов
/ 21 сентября 2011

Почему бы не переместить show как say_hello метод?

class SayHello(unicode):
    _name = u""
    def get_name(self):
        return self._name

    def set_name(self, value):
        self._name = value

    def show(self, name):
        self.name = name
        print(self, self.name)

    name = property(get_name, set_name)

say_hello = SayHello('hello')
say_hello.show('Jim')

Вы должны избегать использования глобальных переменных, если в этом нет особой необходимости.

0 голосов
/ 21 сентября 2011

_name в данном случае локально для функции setName(), поскольку каждое имя переменной присваивается в функции.

Если у вас нет оператора global или в 3.x, заявление nonlocal - которое поможет вам в этом случае.

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