پایتون از "نوعنما"های اختیاری (که بهشون "type hints" یا "type annotations" هم میگن) پشتیبانی میکنه.
این "نوعنماها" یا annotationها یه سینتکس خاص هستن که بهت اجازه میدن نوع یه متغیر رو مشخص کنی.
با مشخص کردن نوع متغیرها، ویرایشگرها و ابزارها میتونن پشتیبانی بهتری بهت بدن.
این فقط یه آموزش سریع / یادآوری در مورد نوعنماهای پایتونه. فقط حداقل چیزایی که برای استفاده ازشون با FastAPI لازمه رو پوشش میده... که در واقع خیلی کمه.
FastAPI کاملاً بر پایه این نوعنماهاست و این بهش کلی مزیت و فایده میده.
ولی حتی اگه هیچوقت از FastAPI استفاده نکنی، بازم یادگیری یه کم در موردشون به نفعته.
Note
اگه حرفهای پایتونی و همهچیز رو در مورد نوعنماها میدونی، برو سراغ فصل بعدی.
سینتکس با استفاده از typing با همه نسخهها، از پایتون 3.6 تا جدیدترینها، از جمله پایتون 3.9، 3.10 و غیره سازگاره.
با پیشرفت پایتون، نسخههای جدیدتر پشتیبانی بهتری برای این نوعنماها دارن و توی خیلی موارد حتی لازم نیست ماژول typing رو وارد کنی و ازش برای تعریف نوعنماها استفاده کنی.
اگه بتونی برای پروژهات از یه نسخه جدیدتر پایتون استفاده کنی، میتونی از این سادگی اضافه بهره ببری.
توی همه مستندات، مثالهایی هستن که با هر نسخه پایتون سازگارن (وقتی تفاوتی هست).
مثلاً "Python 3.6+" یعنی با پایتون 3.6 یا بالاتر (مثل 3.7، 3.8، 3.9، 3.10 و غیره) سازگاره. و "Python 3.9+" یعنی با پایتون 3.9 یا بالاتر (مثل 3.10 و غیره) سازگاره.
اگه بتونی از جدیدترین نسخههای پایتون استفاده کنی، از مثالهای نسخه آخر استفاده کن، چون اونا بهترین و سادهترین سینتکس رو دارن، مثلاً "Python 3.10+".
استفاده از Optional[str] به جای فقط str به ویرایشگر کمک میکنه خطاهایی که ممکنه فکر کنی یه مقدار همیشه str هست رو پیدا کنه، در حالی که میتونه None هم باشه.
Optional[Something] در واقع میانبر برای Union[Something, None] هست، این دو تا معادلن.
یعنی توی پایتون 3.10، میتونی از Something | None استفاده کنی:
اگه از نسخه پایتون زیر 3.10 استفاده میکنی، یه نکته از دید خیلی شخصی خودم:
🚨 از Optional[SomeType] استفاده نکن
به جاش ✨ از Union[SomeType, None] استفاده کن ✨.
هر دو معادلن و زیر پوسته یکیان، ولی من Union رو به Optional ترجیح میدم چون کلمه "اختیاری" انگار暗示 میکنه که مقدار اختیاریه، در حالی که در واقع یعنی "میتونه None باشه"، حتی اگه اختیاری نباشه و هنوز لازم باشه.
فکر میکنم Union[SomeType, None] واضحتر نشون میده چی معنی میده.
فقط بحث کلمات و اسمهاست. ولی این کلمات میتونن رو طرز فکر تو و تیمت نسبت به کد تأثیر بذارن.
این نوعهایی که پارامترهای نوع رو توی کروشهها میگیرن بهشون نوعهای عمومی یا Generics میگن، مثلاً:
میتونی از همون نوعهای داخلی بهعنوان نوعهای عمومی استفاده کنی (با کروشهها و نوعها داخلشون):
list
tuple
set
dict
و همونطور که توی پایتون 3.8 بود، از ماژول typing:
Union
Optional (همونطور که توی پایتون 3.8 بود)
...و بقیه.
توی پایتون 3.10، بهعنوان جایگزین برای استفاده از نوعهای عمومی Union و Optional، میتونی از خط عمودی (|) برای تعریف اتحادیه نوعها استفاده کنی، که خیلی بهتر و سادهتره.
میتونی از همون نوعهای داخلی بهعنوان نوعهای عمومی استفاده کنی (با کروشهها و نوعها داخلشون):
list
tuple
set
dict
و همونطور که توی پایتون 3.8 بود، از ماژول typing:
Pydantic یه کتابخونه پایتونه برای اعتبارسنجی دادهها.
"شکل" دادهها رو بهعنوان کلاسهایی با ویژگیها تعریف میکنی.
و هر ویژگی یه نوع داره.
بعد یه نمونه از اون کلاس رو با یه سری مقدار میسازی و اون مقدارها رو اعتبارسنجی میکنه، به نوع مناسب تبدیلشون میکنه (اگه لازم باشه) و یه شیء با همه دادهها بهت میده.
و با اون شیء نهایی همه پشتیبانی ویرایشگر رو میگیری.
Pydantic یه رفتار خاص داره وقتی از Optional یا Union[Something, None] بدون مقدار پیشفرض استفاده میکنی، میتونی توی مستندات Pydantic در مورد فیلدهای اختیاری لازم بیشتر بخونی.
پایتون یه قابلیت هم داره که بهت اجازه میده متادیتا اضافی رو توی این نوعنماها بذاری با استفاده از Annotated.
توی پایتون 3.9، Annotated بخشی از کتابخونه استاندارده، پس میتونی از typing واردش کنی.
fromtypingimportAnnotateddefsay_hello(name:Annotated[str,"this is just metadata"])->str:returnf"Hello {name}"
توی نسخههای زیر پایتون 3.9، Annotated رو از typing_extensions وارد میکنی.
با FastAPI از قبل نصب شده.
fromtyping_extensionsimportAnnotateddefsay_hello(name:Annotated[str,"this is just metadata"])->str:returnf"Hello {name}"
خود پایتون با این Annotated کاری نمیکنه. و برای ویرایشگرها و ابزارهای دیگه، نوع هنوز str هست.
ولی میتونی از این فضا توی Annotated استفاده کنی تا به FastAPI متادیتای اضافی در مورد اینکه چطور میخوای برنامهات رفتار کنه بدی.
نکته مهم اینه که اولین پارامتر نوع که به Annotated میدی، نوع واقعی هست. بقیش فقط متادیتا برای ابزارهای دیگهست.
الان فقط باید بدونی که Annotated وجود داره، و اینکه پایتون استاندارده. 😎
بعداً میبینی که چقدر قوی میتونه باشه.
Tip
اینکه این پایتون استاندارده یعنی هنوز بهترین تجربه توسعهدهنده رو توی ویرایشگرت، با ابزارهایی که برای تحلیل و بازسازی کدت استفاده میکنی و غیره میگیری. ✨
و همینطور کدت با خیلی از ابزارها و کتابخونههای دیگه پایتون خیلی سازگار میمونه. 🚀
FastAPI از این نوعنماها استفاده میکنه تا چند تا کار بکنه.
با FastAPI پارامترها رو با نوعنماها تعریف میکنی و اینا رو میگیری:
پشتیبانی ویرایشگر.
چک نوعها.
...و FastAPI از همون تعریفها برای اینا استفاده میکنه:
تعریف نیازها: از پارامترهای مسیر درخواست، پارامترهای کوئری، هدرها، بدنهها، وابستگیها و غیره.
تبدیل داده: از درخواست به نوع مورد نیاز.
اعتبارسنجی داده: که از هر درخواست میاد:
تولید خطاهای خودکار که به کلاینت برمیگرده وقتی داده نامعتبره.
مستندسازی API با استفاده از OpenAPI:
که بعدش توسط رابطهای کاربری مستندات تعاملی خودکار استفاده میشه.
اینا شاید همهش انتزاعی به نظر بیاد. نگران نباش. همه اینا رو توی عمل توی آموزش - راهنمای کاربر میبینی.
نکته مهم اینه که با استفاده از نوعهای استاندارد پایتون، توی یه جا (به جای اضافه کردن کلاسهای بیشتر، دکوراتورها و غیره)، FastAPI کلی از کار رو برات انجام میده.
Info
اگه همه آموزش رو گذروندی و برگشتی که بیشتر در مورد نوعها ببینی، یه منبع خوب "تقلبنامه" از mypy هست.