Какова связь между областью видимости и пространствами имен в Python?

12

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

  • Область действия определяет область кода, в которой доступно имя.
  • Правило LEGB определяет способ поиска имен.
  • Пространство имен - это место, где вы ищите имена.

Тогда я читаю:

  • «имена привязываются к пространству имен в соответствии с тем, где они назначены ...» (что, я считаю, относится к области действия в лексической области видимости).
  • msgstr "функции добавляют дополнительный слой пространства имен в ваши программы" [ ref. ] (они не добавляют дополнительную локальную область?)
  • «все имена, назначенные в определении функции, помещаются в локальную область (пространство имен, связанное с вызовом функции)».
  • «глобальная область действия, то есть пространство имен, в котором находятся переменные, созданные (назначенные) на верхнем уровне файла модуля».

* все цитаты взяты из изучения Python 5-е издание ch17

Являются ли пространства имен в Python способом реализации областей? Это одно и то же? Кто-нибудь может просветить меня?

Nikos
источник
1
Не могли бы вы дать ссылки на цитаты - я мог бы найти одну, но не другую.
Джоншарп
1
Пространства имен - это только один тип области видимости. См. Stackoverflow.com/questions/291978/…
Роберт Харви

Ответы:

16

Пространство имен - это словарь, сопоставляющий имена (как строки) со значениями. Когда вы делаете назначение, например a = 1, вы мутируете пространство имен. Когда вы делаете ссылку, например print(a), Python просматривает список пространств имен, чтобы попытаться найти его с именем в качестве ключа.

А область применения определяет , какие пространства имен будут рассмотрены в и в каком порядке. Область действия любой ссылки всегда начинается в локальном пространстве имен и перемещается наружу, пока не достигнет глобального пространства имен модуля, прежде чем перейти к builtins(пространству имен, которое ссылается на предопределенные функции и константы Python, такие как rangeи getattr), которое является концом строки ,

Представьте, что у вас есть функция с именем inner, вложенная в глобальную функцию с именем outerи innerсодержащая ссылку на имя. Python сначала смотрит в innerпространство имен. Если имени там нет, Python просматривает outerпространство имен. Если это не удается, Python пробует globalпространство имен модуля , затем builtinпространство имен, в конечном итоге выбрасывая, NameErrorесли имя не найдено.

Когда мы говорим, что xнаходится в пространстве имен функции, мы имеем в виду, что оно определено там, локально внутри функции. Когда мы говорим, что xнаходится в области действия функции, мы имеем в виду, что она xнаходится либо в пространстве имен функции, либо в любом из внешних пространств имен, в которое вложено пространство имен функции.

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

Термины могут использоваться почти взаимозаменяемо, но это не потому, что они означают одно и то же; это потому, что они во многом совпадают в том, что они подразумевают.

Карл Смит
источник
3
«Термины могут использоваться почти взаимозаменяемо, но это не потому, что они означают одно и то же; это потому, что они во многом совпадают в том, что они подразумевают».
Никос
2
Этот ответ верен по духу, но не точен в деталях. Классы в Python не вводят новое пространство имен, поэтому атрибуты класса должны быть дополнены именем класса и почему атрибуты экземпляра должны быть дополнены именем экземпляра. Уровни пространства имен в Python от внутреннего к внешнему: Локальный, Включающий, Глобальный и Встроенный. Класс может быть определен на любом из этих уровней, но члены класса всегда должны быть квалифицированными.
Роб Смоллшир
Вы правы. Классы не работают так, как я сказал. Я думал, что они создают лексическую область видимости, как функцию, но это не так. Пожалуйста, обновите ответ, если у вас есть время, иначе я сделаю это в какой-то момент. Спасибо.
Карл Смит
1
+1 Блестящий ответ, инкапсулируя такую ​​тонкость так экономно. Я нашел это очень полезным, спасибо!
искатель
1
«Пространство имен является хэшем имени, пар значений, много , как словарь Python» - я уверен , что пространства имен будут сохранены как питон словари. Например, вы можете редактировать глобальное пространство имен, вызывая globals (), что позволяет напрямую изменять словарь для привязки объектов и имен: например, globals () [name] = "object". Отличный ответ иначе.
Эван Росика
4

Существует отличная статья о пространствах имен Python здесь . Чтобы процитировать соответствующую часть, чтобы ответить на ваш вопрос об отношении между областями и пространствами имен:

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

Например, представьте простую программу прокатки штампов:

import random  # 'random' is in module namespace

def roll(sides=6):  # 'roll' is in module namespace, 'sides' is in roll's
    return random.randint(1, sides)  # both 'random' and 'sides' are in scope here

# but sides can't be accessed out here 

roll имеет собственное пространство имен , но имена в пространстве имен модуля также находятся в области видимости .

jonrsharpe
источник
@CarlSmith отмечает, что в ранней документации по Python сказано то же самое: «Область действия - это текстовая область программы Python, где пространство имен доступно напрямую.« Прямой доступ »здесь означает, что неквалифицированная ссылка на имя пытается найти имя в пространстве имен. "
Jonrsharpe
@CarlSmith, кроме дополнительной нелокальной / охватывающей области, это сильно изменилось? Я думаю, что мы говорим одно и то же - пространство имен содержит имена и значения, а область действия сообщает вам, какие пространства имен доступны.
Джоншарп
Я удалил свои старые комментарии.
Карл Смит