Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 3, 2015 21:52:58

ArtikUA
Зарегистрирован: 2015-05-14
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Область видимости и ссылки на аргументы

Есть словарь и две функции: первая переворачивает значение ключа name этого словаря, а вторая - делает все буквы заглавными:

def first(town):
    town['name'] = town['name'][::-1]
    return town
def second(town):
    town['name'] = town['name'].upper()
    return town
town = {'name': 'Moscow', 'population': '10000000'}
town = first(town)
town = second(town)
print(town['name'])
Всё работает отлично, но в каждом аргументе при объявлении функции IDE ругается на “Shadows name ‘town’ from outer scope”

И в самом деле, если мы сделаем так:
def first():
    town['name'] = town['name'][::-1]
def second():
    town['name'] = town['name'].upper()
town = {'name': 'Moscow', 'population': '10000000'}
first()
second()
print(town['name'])
То результат не изменится.
Почему функции видят то, что по идее должно быть за пределами области видимости?
Я ведь не делал global town
Как сделать что бы всё было на “чистых” функциях?

Отредактировано ArtikUA (Авг. 3, 2015 21:54:17)

Офлайн

#2 Авг. 3, 2015 23:43:36

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Область видимости и ссылки на аргументы

Потому что о реализации области видимости в Питоне вы толкьо слышали, а не изучали. Он работает ровно так как и положено. Книга Лутца “Програмируем с Python”(3 изд.) глава 16: Области видимости функции. Вырезка:

Разрешение имен: правило LEGB
Для инструкции def:
• Поиск имен ведется самое большее в четырех областях видимости:
локальной, затем в объемлющей функции (если таковая имеется),
затем в глобальной и, наконец, во встроенной.
По умолчанию операция присваивания создает локальные имена.
• Глобальные объявления отображают имена на область видимости
вмещающего модуля.
Другими словами, все имена, которым присваиваются значения
внутри инструкции def (или внутри выражения lambda, с которым мы
познакомимся позже), по умолчанию являются локальными; функции могут
использовать имена в лексически (т. е., физически) объемлющих
функциях и в глобальной области видимости, но чтобы иметь возможность
изменять их, они должны быть объявлены глобальными. Схема
разрешения имен в языке Python иногда называется правилом LEGB,
название которого состоит из первых букв названий областей видимости:
• Когда внутри функции выполняется обращение к неизвестному
имени, интерпретатор пытается отыскать его в четырех областях
видимости - в локальной (local, L), затем в локальной области
любой объемлющей инструкции def (enclosing, E) или в выражении
lambda, затем в глобальной (global, G) и, наконец, во встроенной
(built-in, Б). Поиск завершается, как только будет найдено первое
подходящее имя.
• Когда внутри функции выполняется операция присваивания (а не
обращение к имени внутри выражения), интерпретатор всегда
создает или изменяет имя в локальной области видимости, если в этой
функции оно не было объявлено глобальным.
• Когда выполняется присваивание имени за пределами функции (т.е.
на уровне модуля или в интерактивной оболочке), локальная область
видимости совпадает с глобальной - с пространством имен модуля.
Т.е. механизм поиска переменной с именем Foo и присваивание переменной имени Foo - существенно отличается.

Если брать определение чистой функции, то скорее всего так:
def first(value):
    return value[::1]
town['name'] = first(town['name'])



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Авг. 4, 2015 11:05:39

ArtikUA
Зарегистрирован: 2015-05-14
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Область видимости и ссылки на аргументы

JOHN_16
Книга Лутца “Програмируем с Python”(3 изд.) глава 16: Области видимости функции. Вырезка:
Спасибо, то что надо!

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version