Scope در پایتون چیست؟
در پایتون، Scope یا «محدوده دسترسی» مشخص میکند که یک متغیر در کدام قسمت از برنامه قابل استفاده است. یادگیری Scope یکی از مفاهیم مهم در کار با متغیرها و توابع پایتون است.
اگر بدانیم یک متغیر در چه محدودهای ساخته شده است، بهتر میتوانیم رفتار برنامه را درک کنیم و از خطاهای مربوط به متغیرها جلوگیری کنیم.
Scope در پایتون چیست؟
Scope محدودهای از برنامه است که در آن میتوانیم به یک متغیر دسترسی داشته باشیم.
برای مثال، متغیری که داخل یک تابع ساخته میشود معمولاً فقط در همان تابع قابل دسترسی است.
def greet():
name = "Ali"
print(name)
greet()
# print(name) # خطا
در این مثال، متغیر name داخل تابع ساخته شده است؛
بنابراین یک متغیر محلی یا Local Variable محسوب میشود.
انواع Scope در پایتون
به صورت ساده، در پایتون با چند محدوده مهم روبهرو هستیم:
| Scope | توضیح |
|---|---|
| Local | متغیری که داخل یک تابع ایجاد میشود. |
| Enclosing | محدوده تابع بیرونی در توابع تو در تو. |
| Global | متغیری که در سطح اصلی فایل تعریف شده است. |
| Built-in | نامها و توابع داخلی خود پایتون. |
Local Scope چیست؟
وقتی متغیری داخل یک تابع تعریف شود، آن متغیر معمولاً دارای Local Scope است.
def calculate():
price = 100
tax = 10
print(price + tax)
calculate()
در این مثال، متغیرهای price و tax
فقط در محدوده تابع calculate() قابل استفاده هستند.
Global Scope چیست؟
اگر یک متغیر خارج از توابع و در سطح اصلی فایل پایتون تعریف شود، معمولاً دارای Global Scope است.
language = "Python"
def show_language():
print(language)
show_language()
print(language)
در این مثال، متغیر language در سطح اصلی برنامه
تعریف شده و تابع میتواند مقدار آن را بخواند.
تفاوت Local و Global
| ویژگی | Local | Global |
|---|---|---|
| محل تعریف | داخل تابع | خارج از تابع |
| محدوده دسترسی | محدوده تابع | سطح کلی برنامه |
| استفاده خارج از تابع | معمولاً امکانپذیر نیست | قابل دسترسی است |
وقتی نام متغیرها یکسان باشد چه اتفاقی میافتد؟
ممکن است یک متغیر Global و یک متغیر Local نام یکسانی داشته باشند. در این حالت، داخل تابع متغیر محلی اولویت دارد.
name = "Ali"
def show_name():
name = "Reza"
print(name)
show_name()
print(name)
خروجی:
Reza
Ali
داخل تابع مقدار Reza استفاده شده است؛
اما خارج از تابع مقدار Global یعنی Ali باقی میماند.
کلمه کلیدی global
اگر بخواهیم داخل یک تابع مقدار یک متغیر Global را تغییر دهیم،
میتوانیم از کلمه کلیدی global استفاده کنیم.
count = 0
def increase():
global count
count += 1
increase()
increase()
print(count)
خروجی:
2
چرا بدون global نمیتوانیم مقدار Global را تغییر دهیم؟
اگر داخل تابع برای یک نام مقدار جدیدی قرار دهیم، پایتون آن نام را به عنوان یک متغیر محلی در نظر میگیرد.
score = 10
def change_score():
score = 20
print(score)
change_score()
print(score)
خروجی:
20
10
متغیر داخل تابع یک متغیر Local جدید است و متغیر Global تغییر نکرده است.
Enclosing Scope چیست؟
وقتی یک تابع داخل تابع دیگری تعریف شود، تابع داخلی میتواند به متغیرهای تابع بیرونی دسترسی داشته باشد. این محدوده را میتوان Enclosing Scope نامید.
def outer():
message = "Hello"
def inner():
print(message)
inner()
outer()
تابع inner() متغیر message را از
تابع بیرونی دریافت میکند.
کلمه کلیدی nonlocal
اگر بخواهیم مقدار متغیر تابع بیرونی را از داخل تابع داخلی
تغییر دهیم، میتوانیم از nonlocal استفاده کنیم.
def outer():
count = 0
def inner():
nonlocal count
count += 1
print(count)
inner()
inner()
outer()
خروجی:
1
2
Built-in Scope چیست؟
پایتون تعدادی نام و تابع داخلی دارد که در بسیاری از برنامهها بدون تعریف مجدد قابل استفاده هستند.
print("Python")
numbers = [1, 2, 3]
print(len(numbers))
print(max(numbers))
توابعی مانند print()، len() و
max() از امکانات داخلی پایتون هستند.
قانون LEGB در پایتون
پایتون برای پیدا کردن یک نام، محدودهها را با ترتیب مشخصی بررسی میکند. این ترتیب با نام LEGB شناخته میشود.
محدوده فعلی تابع
E = Enclosing
محدوده تابع بیرونی
G = Global
محدوده کلی فایل
B = Built-in
نامهای داخلی پایتون
بنابراین وقتی پایتون با نامی مثل name روبهرو میشود،
برای پیدا کردن آن ابتدا محدوده Local را بررسی میکند،
سپس Enclosing، بعد Global و در نهایت Built-in.
یک مثال برای درک LEGB
name = "Global"
def outer():
name = "Enclosing"
def inner():
name = "Local"
print(name)
inner()
outer()
چون متغیر name در محدوده Local وجود دارد،
مقدار Local چاپ میشود.
اشتباه رایج در Scope
یکی از اشتباهات رایج این است که تصور کنیم متغیری که داخل یک تابع ساخته شده، در تمام برنامه قابل استفاده است.
def create_user():
username = "admin"
create_user()
print(username)
این کد خطا ایجاد میکند، زیرا username در محدوده
محلی تابع ساخته شده است.
Scope و پارامترهای تابع
پارامترهای یک تابع نیز در محدوده همان تابع قرار دارند.
def greet(name):
message = "Hello " + name
print(message)
greet("Ali")
در این مثال، هم name و هم message
در محدوده تابع قرار دارند.
Scope و حلقهها
برخلاف بعضی زبانهای برنامهنویسی، در پایتون یک حلقه
for به تنهایی Scope جدیدی ایجاد نمیکند.
for i in range(3):
print(i)
print(i)
در این مثال، متغیر i بعد از پایان حلقه نیز در همان
محدوده قابل دسترسی است.
Scope و شرط if
بلوکهای شرطی مانند if نیز به تنهایی یک Local Scope
جدید ایجاد نمیکنند.
if True:
message = "Python"
print(message)
متغیر message در این مثال بعد از شرط نیز قابل دسترسی است.
چه زمانی از global استفاده کنیم؟
کلمه کلیدی global کاربرد مشخصی دارد، اما بهتر است
بدون نیاز از آن استفاده نکنیم.
در برنامههای بزرگ، استفاده زیاد از وضعیت Global میتواند
وابستگی بین قسمتهای مختلف برنامه را بیشتر کند.
معمولاً استفاده از پارامترهای تابع و برگرداندن مقدار با
return ساختار قابل کنترلتری ایجاد میکند.
روش بهتر به جای Global Variable
در بسیاری از مواقع میتوانیم مقدار را به تابع ارسال کنیم
و نتیجه را با return دریافت کنیم.
def increase(number):
return number + 1
score = 10
score = increase(score)
print(score)
این روش باعث میشود تابع ورودی و خروجی مشخصی داشته باشد.
تمرین عملی Scope
برنامهای بنویسید که یک متغیر Global به نام
counter داشته باشد.
سپس تابعی به نام increase() بسازید که مقدار
counter را یک واحد افزایش دهد.
تابع را سه بار اجرا کنید و مقدار نهایی را چاپ کنید.
پاسخ تمرین
counter = 0
def increase():
global counter
counter += 1
increase()
increase()
increase()
print(counter)
خروجی:
3
جمعبندی Scope در پایتون
Scope مشخص میکند یک نام یا متغیر در چه محدودهای قابل دسترسی است.
- Local: محدوده داخل تابع
- Enclosing: محدوده تابع بیرونی
- Global: محدوده کلی برنامه
- Built-in: نامهای داخلی پایتون
دو کلمه کلیدی مهم در این موضوع نیز
global و nonlocal هستند.
درک قانون LEGB به شما کمک میکند بفهمید پایتون هنگام پیدا کردن یک متغیر چه محدودههایی را بررسی میکند.
سؤالات متداول
Scope در پایتون چیست؟
Scope محدودهای است که یک متغیر یا نام در آن قابل دسترسی است.
Local Scope چیست؟
محدودهای است که معمولاً برای متغیرهای تعریفشده داخل یک تابع ایجاد میشود.
Global Scope چیست؟
محدوده سطح اصلی فایل است که متغیرهای تعریفشده خارج از توابع معمولاً در آن قرار میگیرند.
global در پایتون چه کاربردی دارد؟
با global میتوان داخل یک تابع به نام Global اشاره کرد
و مقدار آن را تغییر داد.
nonlocal چه کاربردی دارد؟
nonlocal برای اشاره به متغیری در محدوده تابع بیرونی
در توابع تو در تو استفاده میشود.