پایتون همواره یک زبان برنامه نویسی پویا یا داینامیک بوده و این بدان معناست که شما برای تعریف متغیر و یا خروجی توابع، نیازی به تعیین کردن نوع داده (Data Type) آن ندارید چرا که در ساختار زبان های برنامه نویسی داینامیک، نوع دادهها در حین اجرا برنامه، براساس مقادیری که به آن داده شده تعیین میشود. اما اگر بخواهیم واضحتر و قبل از اجرا این نوع داده را تعیین کنیم چه؟
پایتون، تا حدی برای حل این مشکل PEP 484 را معرفی کرد. روشی که نه تمام و کمال، اما حس و حال بودن در دنیای یک زبان برنامه نویسی ایستا یا استاتیک را به شما میدهد.
موضوعی که در این ویژگی نهفته است چیزیست تحت عنوان Type Hints. همانطور که از نامش نیز پیداست، هیچ اجبار یا قرارداد خاصی پیاده سازی نشده که کاربر را مجبور به یک انتخاب خاص بکند بلکه در نهایت تنها یکسری Hint یا نکات است. بنابراین این موارد به صورت پیشفرض تاثیر مستقیمی روی مفسر نمیگذارند و قرار نیست چیز خاصی را بررسی کنند. البته روشی برای مجبور کردن مفسر به Type Checking یا بررسی نوع دادهای را نیز داریم که به صورت استاندارد در پایتون پیاده سازی نشده و برای اینکار شما نیاز دارید که از کتابخانههای دیگری استفاده کنید.
مقدمهای بر Type Hints
اگر نسبت به زبانهای برنامه نویسی استاتیک مانند سی، جاوا، سی شارپ و... پیش زمینه آموزشی داشته باشید، موضوعاتی که قصد داریم از آن صحبت کنیم برایتان ناآشنا نخواهد بود. اما اگر برنامه نویس پایتون بودهاید و تا به حال سراغ هیچ زبان دیگری نرفتهاید باید بگویم که قرار است با مفاهیم جدیدی آشنا شوید.
برای آشنایی با این موضوع بیایید با یک مثال شروع کنیم. یک تابع در پایتون ایجاد میکنیم که دو عدد را از ورودی دریافت کرده و آنها را با همدیگر جمع میکند:
def add_numbers(num1, num2):
return num1 + num2print(add_numbers(3, 5)) # 8
هیچ موضوع جدیدی در قطعه کد بالا وجود ندارد که بخواهیم آن را توضیح بدهیم. اما همین قطعه کد چه مشکلی دارد؟ مشکلی که در این قطعه کد وجود دارد این است که هر نوع دادهای که بخواهید را میتوانید به عنوان پارامترهای تابع وارد کنید و در زمان اجرا با مشکلات اجرایی روبرو شوید. برای مثال شما میتوانید یک مقدار رشتهای، عدد صحیح، اعشاری، شرطی و... را وارد کنید که این موارد در عملیات جمع شدن با همدیگر مشکل دارند.
به همین دلیل است که ما در اینجا باید از Type Hint استفاده کنیم. حالتی که به کاربر این پیام را میدهد که از چه نوع دادهای باید استفاده کند. البته همانطور که گفته شد این تنها به عنوان یک پیام نمایش داده میشود و در نهایت اگر کاربر دوباره به صورت اشتباه پارامتر را وارد کند نتیجه مانند قبل خواهد بود.
چگونه Type Hintها را در پایتون پیاده سازی کنیم؟
برای پیاده سازی Type Hint در پایتون شما میتوانید از دو تکنیک کلی استفاده کنید. یکی از این تکنیکها برای نوع دادهای پارامترهای یک تابع است و تکنیک دیگر برای تعیین نوع دادهای خروجی خود تابع به کار میرود. در ادامه هر دو این حالتها را بررسی خواهیم کرد:
- در حالت اول بعد از هر پارامتر یک علامت ( : ) دو نقطه را قرار دهید و بعد نوع دادهای مورد نظر را وارد کنید.
- در حالت دوم بعد از تعیین پارامترها با استفاده از علامت ( <- ) میتوانید نوع دادهای برگشتی یک تابع را تعیین کنید.
در زیر میتوانید یک مثال از هر دو حالت را مشاهده کنید:
def add_numbers(num1: int, num2: int) -> int:
return num1 + num2print(add_numbers(3, 5)) # 8
نکته: اگر شما با تابعی کار میکنید که قرار نیست هیچ خروجی داشته باشد میتوانید در مثال بالا بجای int از none استفاده کنید:
def add_numbers(num1: int, num2: int) -> None:
print(num1 + num2)add_numbers(3, 5) # 8
جدای از نوع دادهای، شما میتوانید یک مقدار پیشفرض را نیز برای هر پارامتر تعیین کنید. برای مثال پارامتر دومتان میتواند به صورت پیشفرض حاوی عدد ۱۰ باشد. به مثال زیر توجه کنید:
def add_numbers(num1: int, num2: int = 10) -> int:
return num1 + num2print(add_numbers(3)) # 13
همه چیز عالی پیش میرود. اما اگر زمانی که تابع add_numbers
را فراخوانی کردیم و در پارامترها از اعداد اعشاری استفاده کردیم چه اتفاقی میافتد؟ هیچ، همانگونه که قبلا اشاره کردیم همه چیز کار خواهد کرد، اما منطقا نباید چنین باشد.
این دقیقا مشکلی است که Type Hint دارد چرا که در واقع runtime و مفسر را مجبور نمیکند که کار خاصی را انجام دهد.
آشنایی مختصر با نوعهای دادهای
در پایتون نوعهای دادهای متفاوتی وجود دارد که در این قسمت از مطلب قصد دارم شما را با پر استفادهترین آنها آشنا کنم. این موارد را میتوانید در پارامترهای ورودی به عنوان Type Hint استفاده کنید.
- Int : عدد صحیحی است که در بیشتر مواقع اعداد نیز به همین صورت در برنامهها وارد میشوند.
- Float : اعداد اعشار با استفاده از این نوع دادهای شناخته میشود.
- Str : نوع دادهای رشته است که بین کوتیشن قرار میگیرد.
- Bool : نوع دادهای منطقی است که حاوی دو حالت True/False است.
- List : لیست به عنوان یکی از ساختارهای دادهای قابلیپمایش در پایتون شناخته میشود که در بسیاری از مواقع توسط برنامه نویسان استفاده میشود.
- Tuple : تاپل یک ساختار دادهای دیگر و در واقع یک روش دیگر برای ذخیره سازی چندین آیتم در داخل یک متغیر است. تفاوت اصلی با لیست که وجود دارد این است که Tuple قابلیت تغییر را در فرایند برنامه به شکل مستقیم ندارد.
- Dict : دیکشنری یک ساختار دادهای بسیار پر کاربرد و مفید است که در آن دادهها به صورت کلید-مقدار یا Key-Value ذخیره میشود.
جمع بندی
یکی از مشکلات اساسی زبانهای داینامیک نبود امکانات استاندارد و اجباری برای تعیین کردن نوع داده متغیرها، توابع و... است. این موضوع در زمان اجرای برنامهها مشکلات زیادی را به وجود میآورد و همواره باید استرس آن را داشت که به شکلی این موضوع میتواند در فرایند اجرا اپلیکیشن مشکل بوجود بیاورد. مطمئنا runtime پایتون هوشمند بوده و در برخی از مواقع میداند که چگونه به درستی برخورد کند اما این مسئله همواره برای برنامه نویسهای حرفهای یک مشکل بوجود میآورد.
👈 به طور کلی پایتون، یک زبان همه کاره است و قواعد دستوری سادهای دارد. علاوه بر این قابلیت های بسیار زیادی دارد که کمک به نوشتن کدهای اثربخشتری میکنند. با این قابلیتها در مقالهی پرکاربردترین قابلیتهای زبان برنامهنویسی پایتون آشنا شوید.