Python Scope

در پایتون، Scope (دامنهٔ متغیر) تعیین می‌کند که یک نام (name) در کجای برنامه قابل دسترسی است.
به بیان ساده: هر متغیر فقط در محدوده‌ای که تعریف شده قابل استفاده است.

🔹 چهار سطح اصلی Scope (قانون LEGB)

پایتون برای جستجوی نام‌ها از ترتیب LEGB استفاده می‌کند:

  1. Local (L) – متغیرهای تعریف‌شده در داخل یک تابع.

  2. Enclosing (E) – متغیرهای محیطی در توابع تو در تو (تابع والد).

  3. Global (G) – متغیرهای تعریف‌شده در بالاترین سطح فایل (ماژول).

  4. Built-in (B) – نام‌های از پیش تعریف‌شدهٔ پایتون (مثل len, print).

پایتون از داخل به بیرون دنبال متغیر می‌گردد.

🔹 مثال پایه

x = "global" # Global def outer(): x = "enclosing" def inner(): x = "local" print(x) inner() outer()

📌 خروجی:

local

پایتون ابتدا در Local جستجو می‌کند، بعد Enclosing، سپس Global و در آخر Built-in.

🔹 Global و Local

x = 10 # global def my_func(): x = 5 # local print("داخل تابع:", x) my_func() print("خارج تابع:", x)

📌 خروجی:

داخل تابع: 5 خارج تابع: 10

🔹 تغییر متغیر Global در تابع

برای تغییر متغیر سراسری داخل تابع باید از global استفاده کنید:

x = 10 def change(): global x x = 20 change() print(x) # 20

🔹 متغیرهای Enclosing (غیرمحلی)

در توابع تو در تو می‌توان با nonlocal متغیر والد (نه global) را تغییر داد:

def outer(): x = "enclosing" def inner(): nonlocal x x = "changed" inner() print(x) outer()

📌 خروجی:

changed

🔹 Built-in Scope

نام‌هایی مثل len, print, range و … در فضای Built-in قرار دارند و همیشه در دسترس‌اند.

🔹 Shadowing (پوشاندن نام‌ها)

اگر در یک Scope داخلی متغیری همنام تعریف شود، نام بیرونی را می‌پوشاند:

len = 5 print(len) # 5 # print(len("abc")) # خطا چون len دیگر تابع نیست!

✅ نکات مهم

  • بهتر است از global تا حد امکان کم استفاده کنید تا کد قابل پیش‌بینی بماند.

  • برای تغییر متغیر در تابع والد از nonlocal بهره ببرید.

  • آگاه باشید که نام‌های داخلی پایتون (مثل list, dict) را با متغیرهای خود نپوشانید.

💡 تمرین‌های پیشنهادی

  1. تابعی تو در تو بنویس که مقدار یک متغیر Enclosing را با nonlocal تغییر دهد.

  2. برنامه‌ای بساز که نشان دهد بدون global امکان تغییر مستقیم متغیر سراسری وجود ندارد.

  3. متغیری به نام max تعریف کنید و ببینید چگونه تابع داخلی ()max دیگر کار نخواهد کرد.

✅ خلاصه

  • Scope = محدودهٔ دسترسی متغیر.

  • ترتیب جستجو: Local → Enclosing → Global → Built-in (LEGB).

  • از global و nonlocal برای تغییر متغیرهای بیرونی استفاده می‌شود.