DevGang
Авторизоваться

Область действия функций Python

Когда вы используете имя в программе Python, например, имя переменной, имя функции и т.д., Python создает, изменяет или ищет это имя в пространстве имен. Пространство имен - это полный список имен, существующих в данном контексте.

Существует два типа пространств имен: глобальное пространство имен и локальное пространство имен.

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

Когда мы определяем функцию, Python устанавливает для нее локальное пространство имен. Любой объект, объявленный внутри функции, будет доступен только в пределах этой функции, объект считается локальным для этой функции. Попытка получить доступ к локальным объектам вне их области видимости вызовет ошибку NameError. Например:

def demo():
    x = 100
    print(x)

demo()
//100
print(x)
//NameError: name 'x' is not defined

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

Если функция объявляет имя, которое также существует в глобальном пространстве имен, локальное имя имеет приоритет над глобальным и перезаписывает его только внутри этой функции. Пример:


x = 200
def demo():
    x = 100
    print(x)

demo()
//100
print(x)
//200

В приведенном выше примере есть две разные переменные с именем x, одна - в глобальном пространстве имен со значением 200, другая - в локальном пространстве имен функции demo со значением 100. Таким образом, значение x определяется тем, где мы её используем. Внесение любых изменений в x внутри функции demo никак не влияет на значение x вне её области видимости.

Разрешение имен, правило LEGB

Когда мы упоминаем объект по имени, интерпретатор Python использует подход «изнутри наружу», чтобы определить, к какому объекту мы обращаемся. Этот подход часто называют правилом LEGB, которое расшифровывается как Local, Enclosing, Global, Built-in. Вкратце это правило можно описать следующим образом:

  1. Local, первое: Ищите это имя сначала в локальном пространстве имен и используйте локальную версию, если она доступна. Если нет, перейдите к более высокому пространству имен.
  2. Enclosing, второе: Если текущая функция заключена в другую функцию, ищите это имя во внешней функции. Если нет, перейдите к более высокому пространству имен.
  3. Global, третье: Ищите имя в объектах, определенных в глобальном пространстве имен.
  4. Built-in, последнее: Наконец, найдите переменную среди встроенных имен Python.

Если интерпретатор проходит все 4 этапа и не находит имя, то возникает ошибка NameErroris, конечно, если операция не была операцией присваивания, в этом случае объект с таким именем будет создан в локальной области видимости, а ошибка не возникнет.

Пример:


x = 200
def demo():
    x = 300
    def inner():
        print(x)
    inner()

demo()
//300

В приведенном выше случае при вызове print x интерпретатору не удается найти объект с именем x в области видимости функции inner, он переходит к вложенной функции, в которой находит объект x со значением 300, прекращая тем самым поиск. Если бы объект с именем x всё же не был найден в объемлющей функции demo, то был бы возвращен глобальный x со значением 200.

Другие примеры:


x = 500
def demo():
   print(x)
   x = 300
   print(x)

demo()
//500
//300
def demo2():
   y = 400
   def inner():
       print(x + y)
   inner()

demo2()
//900

Оператор global

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

Примеры:


def demo():
   global x
   x = 200

demo()
print(x)
//200

Если существует глобальное имя, аналогичное имени, указанному в операторе global, то все изменения, сделанные с объектом, который он идентифицирует, будут действовать на глобальном уровне.

Примеры:


x = 100
def demo():
    global x
    x = 500

demo()
print(x)
//500

Чтобы объявить несколько глобальных имен в одном глобальном операторе, мы используем ключевое слово global, за которым следуют имена, разделенные запятыми, например:


def demo():
   global x, y, z
   x = 4
   y = 3
   z = x + y

demo()
print(x, y, z)
//4, 3, 7

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

Оператор nonlocal

Оператор nonlocal является близким родственником оператора global. В то время как оператор global делает имя доступным на глобальном уровне, ператор nonlocal делает имя доступным в области видимости вложенной функции. Это также позволяет вложенной функции вносить изменения в переменные, определенные во вложенной функции. Примеры:


def demo():
    x = 400
    def inner():
        nonlocal x
        x = 600
    inner()
    print(x)

demo()
//600
def demo2():
    def inner():
        nonlocal y 
        y = 500
    inner()
    print(y)

demo2()
//500

Примечание: Мы не можем использовать оператор nonlocal с функцией верхнего уровня, при попытке это сделать возникнет SyntaxError.


def demo():
    nonlocal y
    y = 100

demo()
//SyntaxError: no binding for nonlocal 'y' found

Источник:

#Python
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу