پایتونمتوسط۷ دقیقه مطالعهPython 3.12+

محدوده متغیرها و پارامترها

در این درس تفاوت متغیر محلی و سراسری را می‌فهمید، با global و ثابت‌ها کار می‌کنید و پارامترهای پیش‌فرض و آرگومان‌های کلیدی را به کار می‌برید.

آنچه در این درس می‌آموزید

  • تفاوت متغیر محلی و سراسری را تشخیص دهید و پیش‌بینی کنید
  • از کلمه کلیدی global درست و کم‌یاب استفاده کنید
  • پارامتر پیش‌فرض و آرگومان کلیدی را در تعریف و فراخوانی به کار ببرید
نویسنده: تیم داکنامه · بازبینی: ۲۰۲۶-۱۰-۳۰
فهرست مطالب
پیش‌نیاز: توابع

تابع در درس قبل مثل یک کارگر خوب بود؛ اما یک راز را نگفتیم: تابع دنیای خودش را دارد. متغیری که داخل تابع می‌سازید، بیرون آن وجود ندارد و برعکس. فهمیدن این مرزها — به‌علاوه پذیرش هوشمندانه ورودی‌ها — تفاوت تابعِ شکننده و تابعِ مطمئن است.

متغیر محلی؛ دنیای خصوصی تابع

متغیری که داخل تابع ساخته می‌شود محلی (Local) است: از لحظه تعریف تا پایان همان فراخوانی زندگی می‌کند و بعد می‌میرد:

scope_demo.py
message = "outside"

def show():
    message = "inside"
    print(message)

show()
print(message)
خروجی کد

inside outside

دو متغیر مستقل ساخته شده است: یکی داخل تابع و یکی بیرونش. تخصیص داخل تابع، متغیر بیرونی را لمس نکرد؛ وقتی show تمام شد، متغیر محلی‌اش از بین رفت و print(message) بیرونی را دید. این ایزوله‌بودن ویژگی است، نه محدودیت: هر تابع می‌تواند بدون ترس از دست‌اندازی به بقیه برنامه، متغیرهای خودش را داشته باشد.

خواندن و نوشتن متغیر سراسری

متغیر بیرون همه توابع، سراسری (Global) است. خواندنش از داخل تابع آزاد است؛ مثالی که همه در برنامه‌های واقعی دیده می‌شود — ثابت پیکربندی:

tax.py
TAX_RATE = 9  # tax percentage

def with_tax(price):
    return price * (100 + TAX_RATE) / 100

print(f"{with_tax(2500000):,.0f} toman")
خروجی کد

2,725,000 toman

تابع TAX_RATE را فقط می‌خواند؛ نامی که محلی پیدا نشد، بیرون جست‌وجو می‌شود. اما نوشتن سراسری از داخل تابع، بدون اعلام، مجاز نیست: تخصیص counter = counter + 1 داخل تابع، متغیر محلی تازه‌ای می‌سازد و خطای UnboundLocalError می‌دهد. اگر واقعاً لازم بود متغیر سراسری را عوض کنید، کلمه کلیدی global را اعلام می‌کنید:

counter.py
counter = 0

def increase():
    global counter
    counter += 1

increase()
increase()
print(counter)
خروجی کد

2

پارامتر پیش‌فرض

تابع می‌تواند برای پارامترش مقدار پیش‌فرض بگذارد؛ آرگومانی که نیاید، پیش‌فرض استفاده می‌شود:

order.py
def order(tea, sugar=1, saffron=False):
    label = f"Tea {tea}"
    if sugar > 0:
        label += f" with {sugar} sugar cubes"
    if saffron:
        label += " and saffron"
    return label

print(order("Lahijan"))
print(order("Garmsar", sugar=0, saffron=True))
خروجی کد

Tea Lahijan with 1 sugar cubes Tea Garmsar and saffron

در فراخوانی اول، فقط چای مشخص شد؛ sugar پیش‌فرض ۱ گرفت و saffron پیش‌فرض False ماند. در فراخوانی دوم، سفارش‌دهنده هر دو را عوض کرد. پارامترهای پیش‌فرض API تابع را دوستانه می‌کنند: حالت رایج با کمترین تایپ انجام می‌شود و حالت‌های خاص هم در دسترس می‌مانند.

آرگومان کلیدی؛ فراخوانی با نام

در فراخوانی دوم مثال قبل، آرگومان‌ها با نامشان داده شدند: sugar=0. به این می‌گویند آرگومان کلیدی (Keyword Argument) و دو مزیت دارد: ترتیب مهم نیست و خواننده می‌فهمد هر مقدار مال کدام پارامتر است. برای دیدن خطر حالت مقابل، فراخوانی مکانی را روی همین تابع امتحان کنید:

python
print(order("Kashan", True))
خروجی کد

Tea Kashan with True sugar cubes

اینجا True مال کدام پارامتر است؟ بدون مراجعه به تعریف تابع، حدس زدن دشوار است؛ و اتفاق افتاده هم بی‌معناست: True به‌جای sugar نشسته و خودش در جمله چاپ شده. نسخه با نام صریح، هم خواناتر است و هم خطای ترتیب را از ریشه می‌برد:

python
print(order("Kashan", saffron=True))
خروجی کد

Tea Kashan with 1 sugar cubes and saffron

قاعده عملی: آرگومان‌های اجباری به شکل مکانی، بقیه با نام. ضمناً می‌توانید پیش‌فرض و کلیدی را ترکیب کنید؛ آنچه نباید فراموش شود، آرگومان‌های بدون پیش‌فرض هستند که همیشه باید داده شوند.

تمرین‌ها

تمرین

تمرین ۱ — محاسبه تخفیف

تابعی به نام discount بنویسید که قیمت بگیرد و درصد تخفیف با پیش‌فرض ۱۰ داشته باشد و قیمت نهایی را برگرداند. آن را یک‌بار بدون درصد و یک‌بار با درصد ۲۰ برای قیمت ۵۰۰۰۰۰ صدا بزنید و هر دو نتیجه را چاپ کنید.

python
# Write your code here
نمایش راه‌حل
python
def discount(price, percent=10):
    return price * (100 - percent) / 100

print(discount(500000))
print(discount(500000, 20))
خروجی کد

450000.0 400000.0

::: :::

خلاصه

  • متغیر محلی فقط داخل تابع خودش زندگی می‌کند و با پایان فراخوانی از بین می‌رود.
  • خواندن متغیر سراسری از داخل تابع آزاد است؛ نوشتنش نیاز به اعلام global دارد.
  • ثابت‌های سراسری با حروف بزرگ مثل TAX_RATE رایج و بی‌خطرند؛ متغیر سراسری تغییرپذیر نه.
  • پارامتر پیش‌فرض، فراخوانی حالت رایج را ساده می‌کند و آرگومان کلیدی، فراخوانی را خوانا و مستقل از ترتیب می‌کند.
  • ساختار تغییرپذیر هرگز مقدار پیش‌فرض پارامتر نیست؛ جای آن None بگذارید.

توابع می‌توانند توابع دیگر را صدا بزنند؛ حتی می‌توانند خودشان را صدا بزنند. در درس بعدی با بازگشتی، یکی از زیباترین و مرموزترین ایده‌های برنامه‌نویسی، آشنا می‌شوید.

منابع و ارجاع‌ها

درس‌های مرتبط