Table of Contents
تفاوت «پارامتر» و «آرگومان»
در فصل توابع، با مفهوم کلی تعریف تابع آشنا شدهاید. در این بخش، تمرکز ما فقط روی «پارامترها» و «آرگومانها» است؛ یعنی ورودیهایی که یک تابع دریافت میکند.
بهطور ساده:
- پارامتر (Parameter): نامهایی که در تعریف تابع مینویسیم.
- آرگومان (Argument): مقدارهایی که هنگام فراخوانی تابع به آن میدهیم.
مثال:
def greet(name): # name یک پارامتر است
print("سلام", name)
greet("علی") # "علی" یک آرگومان استاینجا:
nameپارامتر تابعgreetاست."علی"آرگومانی است که به تابع داده شده و داخل تابع در متغیرnameقرار میگیرد.
به زبان دیگر:
$$
\text{تابع} + \text{پارامترها} \xrightarrow{\text{فراخوانی با آرگومانها}} \text{اجرا}
$$
پارامترهای موقعیتی (Positional Parameters)
سادهترین نوع پارامترها، پارامترهای معمولی هستند که ترتیب آنها مهم است. به اینها پارامتر موقعیتی میگوییم؛ چون آرگومانها بر اساس موقعیت به آنها نسبت داده میشوند.
def add(a, b):
print(a + b)
add(3, 5) # a = 3 ، b = 5
add(10, 2) # a = 10 ، b = 2نکتهها:
- تعداد آرگومانها باید با تعداد پارامترهای اجباری یکی باشد.
- ترتیب آرگومانها مهم است.
اگر تعداد کم یا زیاد باشد، معمولاً خطای TypeError دریافت میکنید (جزئیات خطاها در فصل خطاها و اشکالزدایی).
پارامترهای پیشفرض (Default Parameters)
گاهی میخواهیم بعضی پارامترها اختیاری باشند؛ یعنی اگر کاربر چیزی برای آنها نفرستاد، یک مقدار پیشفرض استفاده شود. در این حالت، در تعریف تابع برای آن پارامتر یک مقدار پیشفرض تنظیم میکنیم.
def greet(name, message="سلام"):
print(message, name)
greet("علی") # از مقدار پیشفرض message استفاده میشود
greet("مینا", "درود بر") # مقدار message را خودمان میدهیمدر مثال بالا:
nameیک پارامتر اجباری است (بدون آن تابع خطا میدهد).messageیک پارامتر اختیاری با مقدار پیشفرض"سلام"است.
اگر هنگام فراخوانی، آرگومانی برای message نفرستیم، پایتون از "سلام" استفاده میکند.
چند قانون مهم درباره پارامترهای پیشفرض
- پارامترهای دارای مقدار پیشفرض باید بعد از پارامترهای عادی بیایند.
این درست است:
def func(a, b=10):
print(a, b)این اشتباه است و خطا میدهد:
def func(a=10, b):
print(a, b)پایتون نمیداند آرگومان اول را به کدام پارامتر نسبت بدهد.
- مقدار پیشفرض فقط یکبار هنگام تعریف تابع محاسبه میشود، نه هر بار که تابع اجرا میشود. (اثرات خاص این موضوع را معمولاً در مورد لیستها و دیکشنریها میبینید که بحث آن در مباحث پیشرفتهتر میآید.)
آرگومانهای نامدار (Keyword Arguments)
تا اینجا آرگومانها را فقط بر اساس ترتیب میفرستادیم. در پایتون میتوانیم بهجای ترتیب، نام پارامتر را موقع فراخوانی مشخص کنیم؛ به اینها آرگومان نامدار میگویند.
def introduce(name, age, city):
print("نام:", name)
print("سن:", age)
print("شهر:", city)
# فراخوانی موقعیتی
introduce("سارا", 25, "تهران")
# فراخوانی با آرگومان نامدار
introduce(name="سارا", age=25, city="تهران")
# ترکیب: اول موقعیتی، بعد نامدار
introduce("سارا", city="تهران", age=25)نکتههای مهم:
- اگر از آرگومان نامدار استفاده میکنید، میتوانید ترتیب را عوض کنید؛ چون نام پارامتر مشخص است.
- نمیتوانید بعد از آرگومان نامدار، آرگومان موقعیتی بیاورید.
این اشتباه است:
introduce(name="سارا", 25, city="تهران") # خطادر نتیجه:
- اول آرگومانهای موقعیتی،
- بعد آرگومانهای نامدار.
ترکیب پارامترهای اجباری، پیشفرض و نامدار
میتوانیم تابعهایی بنویسیم که هم پارامتر اجباری داشته باشند، هم پیشفرض. سپس هنگام فراخوانی، هم از آرگومان موقعیتی استفاده کنیم، هم نامدار.
def make_profile(name, age, city="نامشخص"):
print("نام:", name)
print("سن:", age)
print("شهر:", city)
# فقط پارامترهای اجباری
make_profile("علی", 20)
# تغییر دادن مقدار پیشفرض با آرگومان موقعیتی
make_profile("مینا", 30, "اصفهان")
# تغییر دادن مقدار پیشفرض با آرگومان نامدار
make_profile("رضا", 28, city="مشهد")قواعد کلی:
- پارامترهای بدون مقدار پیشفرض، اجباری هستند.
- پارامترهای دارای مقدار پیشفرض، اختیاری هستند.
- هنگام فراخوانی:
- آرگومانهای موقعیتی باید ابتدا بیایند.
- سپس میتوانید آرگومانهای نامدار را (به هر ترتیبی) بنویسید.
تعداد متغیّر آرگومانها: `*args` و `**kwargs` (مقدماتی)
گاهی از قبل نمیدانیم که کاربر قرار است چند آرگومان به تابع بدهد. در این حالت میتوانیم از دو الگو استفاده کنیم:
*argsبرای تعداد دلخواه آرگومان موقعیتی.kwargsبرای تعداد دلخواه آرگومان نامدار**.
در این بخش فقط یک آشنایی مقدماتی میدهیم.
`*args` – آرگومانهای موقعیتی زیاد
def add_all(*numbers):
total = 0
for n in numbers:
total += n
print("جمع =", total)
add_all(1, 2)
add_all(1, 2, 3, 4, 5)نکتهها:
- در تعریف تابع،
*numbersیعنی «همه آرگومانهای موقعیتی اضافی را در یک تاپل به نامnumbersجمع کن». - نام
numbersدلخواه است؛ مهم ستارهاست. مثلاًargsهم رایج است، معادل همان است.
`**kwargs` – آرگومانهای نامدار زیاد
def show_info(**info):
print(info)
show_info(name="علی", age=22)
show_info(city="تهران", job="دانشجو", level="مقدماتی")اینجا:
infoیعنی «همه آرگومانهای نامدار اضافی را در یک دیکشنری** به نامinfoجمع کن».- کلیدهای دیکشنری همان نام پارامترها هستند که موقع فراخوانی استفاده کردهاید.
ترکیب با پارامترهای معمولی
ترتیب کلی پارامترها در تعریف تابع (به صورت ساده) معمولاً این است:
- پارامترهای معمولی (اجباری)
- پارامترهای دارای مقدار پیشفرض
*args**kwargs
یک مثال ساده:
def demo(a, b=10, *args, **kwargs):
print("a:", a)
print("b:", b)
print("args:", args)
print("kwargs:", kwargs)
demo(1)
demo(1, 2, 3, 4, x=100, y=200)خروجی بهطور کلی شبیه این خواهد بود:
a: 1
b: 10
args: ()
kwargs: {}
a: 1
b: 2
args: (3, 4)
kwargs: {'x': 100, 'y': 200}نکات رایج و اشتباهات معمول
۱. فراموش کردن آرگومان اجباری
def greet(name):
print("سلام", name)
greet() # خطا: آرگومان لازم استاگر میخواهید گاهی بدون نام هم کار کند، باید مقدار پیشفرض بدهید:
def greet(name="دوست"):
print("سلام", name)
greet()
greet("مریم")۲. جابهجا نوشتن پارامتر پیشفرض
یادآوری:
def func(a, b=10): # درست
...
def func(a=10, b): # غلط
...۳. استفاده اشتباه از ترتیب آرگومان نامدار و موقعیتی
درست:
introduce("سارا", age=20, city="تبریز")غلط:
introduce(name="سارا", 20, "تبریز") # بعد از نامدار، موقعیتی آوردن مجاز نیستچند تمرین پیشنهادی
۱. تابعی بنویسید به نام power که دو پارامتر base و exp بگیرد و base را به توان exp برگرداند. برای exp مقدار پیشفرض 2 قرار دهید (توان دوم).
۲. تابعی بنویسید به نام full_name که first_name و last_name بگیرد و نام کامل را چاپ کند. طوری بنویسید که بتوانید در فراخوانی، پارامترها را هم به صورت موقعیتی و هم نامدار استفاده کنید.
۳. تابعی بنویسید به نام average که با استفاده از *args، هر تعداد عدد بگیرد و میانگین آنها را چاپ کند. اگر هیچ عددی داده نشد، پیام مناسب چاپ کند.
۴. تابعی بنویسید به نام print_settings که هر تعداد تنظیم با نام (مانند theme="dark"، language="fa") بگیرد و با استفاده از **kwargs آنها را خطبهخط چاپ کند.
سعی کنید این تمرینها را در فایل جداگانه بنویسید و چند بار با آرگومانهای مختلف تست کنید تا مفهوم پارامترها و آرگومانها برایتان کاملاً جا بیفتد.