Python / Хамрах хүрээ (Scope)

Хамрах хүрээ (Scope)

Python-д variable зарлагдсан байршил нь тухайн variable-г хаанаас харж, хэрэглэж болохыг тодорхойлдог. Энэ ойлголтыг scope (хамрах хүрээ) гэнэ. Scope ойлгоогүй бол "Variable олдсонгүй" гэсэн алдаа яагаад гарч байгааг тайлбарлахад хэцүү болдог.

Local ба Global scope

Python-д хоёр үндсэн scope байдаг:

  • Global scope — функцийн гадна зарлагдсан variable; програмын хаанаас ч харагдана
  • Local scope — функцийн дотор зарлагдсан variable; зөвхөн тухайн функцэд л харагдана
python
# Global variable
нэр = "Болд"      # хаанаас ч харагдана

def мэндчилэх():
    # Local variable
    мэдэгдэл = "Сайн уу!"    # зөвхөн энэ функцэд л харагдана
    print(нэр)        # global-г харж болно ✓
    print(мэдэгдэл)   # local-г харж болно ✓

мэндчилэх()
print(нэр)        # global ✓
# print(мэдэгдэл)  # ❌ NameError — функцийн гадна харагдахгүй

Local variable нь global-г далдлана

Функцийн дотор global-тэй нэр ижил variable зарлавал local нь давамгайлна — global-г өөрчлөхгүй:

python
оноо = 100    # global

def шалгах():
    оноо = 50    # шинэ local variable — global-г өөрчлөхгүй
    print(f"Функц дотор: {оноо}")    # 50

шалгах()
print(f"Функц гадна: {оноо}")        # 100 — өөрчлөгдөөгүй

Энэ зан байдал хамгаалалт болдог — функц дотрын өөрчлөлт гадны variable-г санамсаргүй өөрчлөхгүй.

global түлхүүр үг

Функц дотроос global variable-г өөрчлөх шаардлага гарвал global зарлана:

python
тоолуур = 0    # global

def нэмэх():
    global тоолуур
    тоолуур += 1

нэмэх()
нэмэх()
нэмэх()
print(тоолуур)    # 3

⚠️ global хэрэглэхдээ болгоомжилно — кодыг уншихад хэцүү болгодог. Ихэвчлэн return ашиглан утгыг буцааж авах нь дээр:

python
# ✅ Илүү сайн арга — global ашиглахгүйгээр
def нэмэх(тоолуур):
    return тоолуур + 1

тоолуур = 0
тоолуур = нэмэх(тоолуур)
тоолуур = нэмэх(тоолуур)
print(тоолуур)    # 2

Функц дотор функц — enclosing scope

Функц дотор функц зарлавал дотоод функц нь гадаадынхаа variable-г харж чадна:

python
def гадаад():
    мэдэгдэл = "Гадаад функцийн variable"

    def дотоод():
        print(мэдэгдэл)    # enclosing scope-оос харна ✓

    дотоод()

гадаад()
# Гадаад функцийн variable

Дотоод функцийн гадаад variable-г өөрчлөхөд nonlocal ашигладаг:

python
def тоолуур_үүсгэх():
    тоо = 0

    def нэмэх():
        nonlocal тоо
        тоо += 1
        return тоо

    return нэмэх

тоол = тоолуур_үүсгэх()
print(тоол())    # 1
print(тоол())    # 2
print(тоол())    # 3

LEGB дүрэм

Python variable хайхдаа дараах дарааллаар шалгадаг — LEGB:

| Үсэг | Нэр | Тайлбар | | ---- | --------- | ---------------------------------------- | | L | Local | Одоогийн функцийн дотор | | E | Enclosing | Гадаадын функц (nested функц тохиолдолд) | | G | Global | Модулийн дээд түвшин | | B | Built-in | Python-ийн суурилагдсан нэрнүүд |

python
x = "global"      # Global

def гадаад():
    x = "enclosing"    # Enclosing

    def дотоод():
        # x = "local"  # Хэрэв энийг нэмбэл Local давамгайлна
        print(x)        # Enclosing хэрэглэнэ

    дотоод()

гадаад()   # enclosing

# Built-in жишээ: len, print, range зэрэг нь бүгд Built-in scope-д байна

Нийтлэг алдаа ба шийдэл

python
# ❌ Алдаа — функцийн гадна зарлагдаагүй variable ашиглах
def тооцоолох():
    return оноо + 10   # оноо тодорхойлогдоогүй!

# тооцоолох()   →  NameError: name 'оноо' is not defined

# ✅ Шийдэл 1 — параметраар дамжуулах
def тооцоолох(оноо):
    return оноо + 10

print(тооцоолох(80))    # 90

# ✅ Шийдэл 2 — global зарлах (шаардлагатай үед л)
оноо = 80

def тооцоолох():
    global оноо
    return оноо + 10

print(тооцоолох())    # 90

Дараагийн хичээлд:

Scope-ийг ойлголлоо — variable хаана харагддаг, хаана харагдахгүйг мэдэх нь алдааг хурдан олоход их тусална! Дараа нь Python-ийн хамгийн хэрэгтэй өгөгдлийн бүтцийн нэг болох list (жагсаалт) — олон утгыг нэг variable-д хадгалах аргыг судална.