Python. Області видимості імен в Python. Локальні імена. Правила видимості імен. Правило LEGB. Ключове слово global. Перевизначення імен в функціях




Області видимості імен в Python. Локальні та глобальні імена. Правила видимості імен. Правило LEGB. Ключове слово global. Перевизначення імен в функціях


Зміст


Пошук на інших ресурсах:

1. Значення імен в Python

У мові програмування Python все що стосується області видимості імені визначається на основі операції присвоювання. Як тільки в програмі зустрічається деяке ім’я, інтерпретатор здійснює його відповідну обробку. Це може бути створення, зміна або пошук імені в просторі імен (області, де розміщуються імена). У даному випадку, простір імен – це місце в програмному коді, де імені було присвоєне деяке значення. Цей простір імен визначає область видимості даного імені.

 

2. В яких областях видимості можна присвоювати значення іменам змінних?

Згідно філософії Python кожна змінна має ім’я і є об’єктом. Ім’я змінної з’являється у програмі після присвоювання їй деякого значення. Після присвоювання кожне ім’я має свою область видимості (простір імен). Відповідно до області видимості змінної, ця змінна може класифікуватись одним з трьох можливих випадків:

  • локальна змінна – це змінна, якій присвоювання значення відбувається всередині інструкції def (всередині функції) або lambda;
  • нелокальна змінна – це змінна, якій присвоюється значення в межах об’ємлючої інструкції def;
  • глобальна змінна – це змінна, якій присвоюється значення за межами всіх інструкцій def (за межами всіх функцій) або всередині інструкції def з вказанням ключового слова global.

 

3. Локальні імена. Правила видимості локальних імен

Мова Python дозволяє оголошувати функції з допомогою інструкції def. Всередині цієї інструкції можна визначати власні імена. Таким чином виникає поняття локального імені. Локальне ім’я – це ім’я, яке створюється (визначається) всередині функції. Функції визначають вкладені простори імен, які обмежують доступ до імен, визначених всередині цих функцій.

Простір імен локального імені визначається простором імен функції в якому це ім’я визначене. Для локальних імен можна сформулювати наступні правила видимості:

  • ім’я, що визначене всередині функції (всередині інструкції def), є доступним тільки в програмному коді цієї функції з моменту його першого використання;
  • імена, що визначені всередині функції, не конфліктують з іменами, що оголошені (використовуються) за межами функції. Таким чином, всередині функції (інструкції def) та за її межами можуть використовуватись однакові імена;
  • з-за меж функції немає доступу до локальних імен, оголошених всередині функції.

Приклад.

# Локальні імена

# Визначення імен за межами функції - глобальні змінні
a = 'Hello world!' # Ім'я a, яке є рядком
b = [ 2, 3, 8.55, 'Textbook' ] # ім'я b, що є списком

# Визначення імен всередині функції
def Fn():
    a = 2.777 # ім'я a - число з плаваючою комою
    b = { 1:'One', 2:'Two' } # ім'я b - словник
    c = [ 0.1, 0.01, 0.001 ] # ім'я c - список
    print('Fn.a = ', a)
    print('Fn.b = ', b)
    print('Fn.c = ', c)

# Вивести імена, що оголошені за межами функції
print('a = ', a)
print('b = ', b)

# Викликати функцію
Fn()

У вищенаведеному коді фігурує 5 імен. Три імена оголошуються всередині функції. Ці імена не конфліктують з іменами, які оголошені за межами функції навіть, якщо вони співпадають. Так, ім’я a за межами функції є рядком. Таке саме ім’я всередині функції є числом з плаваючою комою. Це означає, що ці імена розміщуються в різних просторах імен.

Результат роботи програми

a = 'Hello world!'
b = [2, 3, 8.55, 'Textbook']
Fn.a = 2.777
Fn.b = {1: 'One', 2: 'Two'}
Fn.c = [0.1, 0.01, 0.001]

 

4. Які області видимості існують в Python?

У мові Python існують чотири області видимості:

  • вбудована область видимості. Ця область видимості включає наперед визначені імена у модулі вбудованих імен. Приклади таких імен: print, open, set, range, slice та інші;
  • глобальна область видимості в межах модуля;
  • локальна область видимості охоплюючих функцій;
  • локальна область видимості всередині функцій. Такі імена оголошуються всередині інструкції def або lambda.

На рисунку 1 відображено доступ до імен в різних областях видимості.

Області видимості Python

Рисунок 1. Області видимості Python

 

5. Як здійснюється пошук імен в областях видимості? Як працює правило LEGB

Якщо в функції (локальна область видимості) оголошено ім’я, то інтерпретатор шукає це ім’я у наступному порядку:

  • у локальній області видимості всередині функції (Local);
  • у локальних областях видимості охоплюючих функцій (Enclosing);
  • у глобальній області видимості (Global);
  • у вбудованій області видимості (Built-in).

Такий порядок відповідає так званому правилу LEGB: Local – Enclosing – Global – Built-in.

Якщо відбувається звертання до імені в глобальній області видимості, то пошук відбувається в цій області а також у вбудованій області (див. рисунок 1).

 

6. Як визначити імена вбудованої області видимості? Приклад

Імена вбудованої області видимості розміщуються в модулі стандартної бібліотеки builtins. Щоб отримати список імен потрібно цей модуль підключити. Список імен отримується з допомогою функції dir.

# Визначення імен вбудованої області видимості

# Імпортувати модуль builtins
import builtins

# Отримати перелік імен у вигляді списку
names = dir(builtins)

# Вивести імена в циклі
for t in names:
    print(t)

Після запуску на виконання програми, буде виведено список вбудованих імен.

Якщо в програмі підключено модуль builtins наступним чином

import builtins

то з допомогою імені builtins. можна звертатись до вбудованих імен. Наприклад

# Створити пусту множину
A = builtins.set()

# Створити пустий список
L = builtins.list()

 

7. Які існують взаємозв’язки між локальною та глобальною областями видимості?

Між локальною та глобальною областями видимості існують наступні взаємозв’язки:

  • модуль – це глобальна область видимості (простір імен). Це область, в якій створюються глобальні змінні на верхньому рівні у файлі модуля. За межами модуля глобальні змінні являються атрибутами об’єкта модуля;
  • глобальна область видимості визначається в єдиному файлі. Глобальні імена в межах цього файлу завжди відносяться до даного модуля;
  • виклик будь-якої функції створює нову локальну область видимості. Ця область видимості має межі, що визначаються інструкцією def або lambda;
  • якщо в програмному коді реалізована рекурсія (функція циклічно викликає сама себе багато разів), то кожен виклик функції створює нову локальну область видимості (простір імен);
  • якщо всередині функції використовується операція присвоєння =, то ця операція створює локальні імена за замовчуванням. Якщо потрібно оголосити глобальне ім’я всередині функції, то перед цим іменем потрібно вказати ключове слово global. Якщо в інструкції def нижнього рівня (у випадку вкладених функцій) потрібно присвоїти значення імені, яке оголошується в інструкції def верхнього рівня, то це ім’я має бути оголошене з ключовим словом nonlocal.

 

8. Як відбувається перевизначення вбудованого   та глобального імен всередині функції? Приклад

Згідно правилу LEGB вбудоване та глобальне імена можуть бути перевизначені всередині функції.

Приклад. У нижченаведеному коді перевизначається глобальне ім’я x та вбудоване ім’я list.

# Перевизначення вбудованих та глобальних імен
# всередині функцій

# 1. Перевизначення вбудованого імені list у функції Fn1()
# 1.1.Визначити функцію Fn1()
def Fn1():
    list = 'This is a text'
    print(list)
    return

# 1.2. Виклик функції Fn1()
Fn1()

# 2. Перевизначення глобального імені x всередині функції
# 2.1. Визначити глобальне ім'я
x = 30

# 2.2. Визначити функцію Fn2(), в якій використовується
#      власне локальне ім'я x
def Fn2():
    # Визначити локальне ім'я
    x = 'Local x'

    # Вивести локальне ім'я на екран
    print(x) # Local x

    return

# Викликати функцію Fn2()
Fn2()

# Вивести глобальне ім'я
print(x) # 30

Після запуску програма видає наступний результат

This is a text
Local x
30

Як видно з результату, вбудоване та локальне ім’я перевизначаються локальними іменами всередині функції.

 

9. Оголошення глобального імені всередині функції. Ключове слово global. Приклад

Глобальне ім’я всередині функції можна оголосити з допомогою ключового слова global. У загальному випадку таке оголошення має вигляд:

def FuncName(parameters):
    ...
    global var
    var = value
    ...
    return

тут

  • FuncName – ім’я функції;
  • var – ім’я, яке оголошується глобальним всередині функції FuncName;
  • value – присвоєння деякого значення глобальному імені

Приклад.

# Глобальні змінні. Ключове слово global

x = 25 # глобальне ім'я

def Fn():
    # оголошення глобального імені t всередині функції
    global t
    t = 30 # присвоїти глобальному імені t значення

    # вивести глобальне ім'я x всередині функції
    print(x)

    return

Fn()

# Використати глобальне ім'я t, оголошене всередині функції Fn()
z = x+t # z = 25+30 = 55
print(z)

 


Зв’язані теми