انواع تابع از نظر ورودی
در واقع، در این درس انواع تابع از نظر ورودی را از پایه و با مثال یاد میگیرید.
بنابراین در درس قبل دیدید که تابع میتواند پارامتر داشته باشد. حالا میخواهیم دقیق ببینیم چند روش برای دادن ورودی وجود دارد، چون هر کدام جای خودش را دارد.
آرگومان ترتیبی
def introduce(name, city):
print(name, "اهل", city, "است")
introduce("علی", "تهران")
همچنین، سادهترین حالت: مقدارها به ترتیب در پارامترها مینشینند. خطرش هم همین است:
introduce("تهران", "علی")
تهران اهل علی است
به این ترتیب، پایتون خطا نمیدهد، چون از نظر او همهچیز درست است. فقط خروجی بیمعنی است.
آرگومان نامی
introduce(city="تهران", name="علی")
علی اهل تهران است
علاوه بر این، وقتی اسم پارامتر را مینویسید، ترتیب دیگر مهم نیست. در توابعی که چند ورودی دارند، این کار کد را خواناتر میکند. مقایسه کنید:
send_email("a@b.com", True, False, True)
send_email("a@b.com", urgent=True, copy=False, archive=True)
در نهایت، خط دوم را شش ماه بعد هم میفهمید. خط اول را نه.
مقدار پیشفرض
def introduce(name, city="تهران"):
print(name, "اهل", city, "است")
introduce("علی")
introduce("زهرا", "شیراز")
در واقع، یک قاعده هست که پایتون سختگیرانه اعمالش میکند: پارامترهای دارای پیشفرض باید بعد از پارامترهای بدون پیشفرض بیایند:
def introduce(city="تهران", name):
pass
SyntaxError: parameter without a default follows parameter with a default
تعداد نامشخص ورودی
بنابراین گاهی از قبل نمیدانید چند ورودی میآید. مثلاً تابعی که میانگین میگیرد:
def average(*numbers):
return sum(numbers) / len(numbers)
print(average(10, 20))
print(average(10, 20, 30, 40))
15.0
25.0
در واقع، علامت ستاره یعنی «هر چند تا که آمد، همه را داخل یک تاپل بریز». بله، دقیقاً همان تاپلی که در درسهای قبل یاد گرفتید.
نسخهی نامیاش هم وجود دارد و نتیجهاش دیکشنری است:
def show(**info):
for key, value in info.items():
print(key, "=", value)
show(name="علی", age=25)
name = علی
age = 25
نامهای args و kwargs که در کدهای دیگران میبینید، فقط قرارداد هستند. آن چیزی که معنا دارد، ستارهها هستند نه اسمها.
اشتباهات رایج
تعداد اشتباه ورودی
def introduce(name, city):
print(name, city)
introduce("علی")
TypeError: introduce() missing 1 required positional argument: 'city'
پیشفرض تغییرپذیر
این یکی از معروفترین دامهای پایتون است و در مصاحبهها مدام پرسیده میشود:
def add_item(item, items=[]):
items.append(item)
return items
print(add_item("سیب"))
print(add_item("موز"))
['سیب']
['سیب', 'موز']
انتظار داشتید بار دوم فقط موز باشد. دلیلش این است که مقدار پیشفرض فقط یک بار و در لحظهی تعریف تابع ساخته میشود، نه در هر بار صدا زدن. راه درست:
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
جمعبندی
ورودی تابع را میتوان ترتیبی یا نامی داد، میتوان برایش پیشفرض گذاشت و میتوان تعدادش را باز گذاشت. هرگز لیست یا دیکشنری را به عنوان مقدار پیشفرض نگذارید.
در درس بعدی طرف دیگر ماجرا را میبینیم: خروجی تابع.
برای مطالعهی بیشتر میتوانید به مستندات رسمی پایتون سر بزنید.
این درس بخشی از دوره آموزش پایتون مقدماتی است.