diff --git a/docs/fa/python-types.md b/docs/fa/python-types.md index 55ccf94a1..c699f0146 100644 --- a/docs/fa/python-types.md +++ b/docs/fa/python-types.md @@ -1,184 +1,578 @@ +# مقدمه‌ای بر انواع نوع های (Types) پایتون +پایتون از "نوع‌نما"های اختیاری (که بهشون "type hints" یا "type annotations" هم می‌گن) پشتیبانی می‌کنه. -# معرفی انواع داده در پایتون (Python Types) +این **"نوع‌نماها"** یا annotationها یه سینتکس خاص هستن که بهت اجازه می‌دن نوع یه متغیر رو مشخص کنی. -پایتون از «نشانه‌های نوع» (type hints) که به آن‌ها «حاشیه‌نویسی نوع» (type annotations) نیز گفته می‌شود، پشتیبانی می‌کند. +با مشخص کردن نوع متغیرها، ویرایشگرها و ابزارها می‌تونن پشتیبانی بهتری بهت بدن. -این **نشانه‌های نوع** یک سینتکس خاص دارند که امکان تعیین نوع داده متغیرها را فراهم می‌کنند. +این فقط یه **آموزش سریع / یادآوری** در مورد نوع‌نماهای پایتونه. فقط حداقل چیزایی که برای استفاده ازشون با **FastAPI** لازمه رو پوشش می‌ده... که در واقع خیلی کمه. -با تعیین نوع متغیرها، ادیتورها و ابزارها می‌توانند تجربه بهتری برای توسعه ارائه دهند. +**FastAPI** کاملاً بر پایه این نوع‌نماهاست و این بهش کلی مزیت و فایده می‌ده. -این یک **مرور سریع و کاربردی** درباره‌ی type hints در پایتون است و تنها حداقل موارد موردنیاز برای استفاده در **FastAPI** را پوشش می‌دهد؛ در واقع، آن‌قدر ساده است که به‌راحتی می‌توان آن را یاد گرفت. +ولی حتی اگه هیچ‌وقت از **FastAPI** استفاده نکنی، بازم یادگیری یه کم در موردشون به نفعته. -‏**FastAPI** کاملاً بر اساس این type hints ساخته شده و از مزایای آن‌ها بهره می‌برد. +/// note -اما حتی اگر از **FastAPI** استفاده نمی‌کنید، یادگیری این مفاهیم همچنان برایتان مفید خواهد بود. +اگه حرفه‌ای پایتونی و همه‌چیز رو در مورد نوع‌نماها می‌دونی، برو سراغ فصل بعدی. -/// note -اگر در پایتون حرفه‌ای هستید و همه‌چیز را درباره‌ی type hints می‌دانید، می‌توانید به فصل بعد بروید. /// -## انگیزه (Motivation) +## انگیزه -بیایید با یک مثال ساده شروع کنیم: +بیاید با یه مثال ساده شروع کنیم: -{\* ../../docs\_src/python\_types/tutorial001.py \*} +{* ../../docs_src/python_types/tutorial001.py *} -خروجی اجرای این برنامه: +وقتی این برنامه رو اجرا کنی، خروجی اینه: ``` John Doe ``` -این تابع کارهای زیر را انجام می‌دهد: +این تابع این کارا رو می‌کنه: + +* یه `first_name` و `last_name` می‌گیره. +* حرف اول هر کدوم رو با `title()` بزرگ می‌کنه. +* ترکیبشون می‌کنه با یه فاصله وسطشون. + +{* ../../docs_src/python_types/tutorial001.py hl[2] *} -- پارامترهای `first_name` و `last_name` را دریافت می‌کند. -- با استفاده از `title()` حرف اول هر کدام را بزرگ می‌کند. -- آن‌ها را با یک فاصله در میانشان ادغام می‌کند. +### ویرایشش کن -{\* ../../docs\_src/python\_types/tutorial001.py hl[2] \*} +این یه برنامه خیلی ساده‌ست. -### ویرایش آن +ولی حالا تصور کن داری از صفر می‌نویسیش. -این یک برنامه‌ی بسیار ساده است. اما تصور کنید در حال نوشتن آن از ابتدا هستید. +یه جایی شروع کردی به تعریف تابع، پارامترهات آماده‌ست... -در مرحله‌ای که تعریف تابع را شروع کرده‌اید و پارامترها را مشخص نموده‌اید... +ولی بعد باید "اون متدی که حرف اول رو بزرگ می‌کنه" رو صدا کنی. -اما باید متدی را فراخوانی کنید که حرف اول را بزرگ می‌کند. +آیا اسمش `upper` بود؟ یا `uppercase`؟ شاید `first_uppercase`؟ یا `capitalize`؟ -آیا `upper` بود؟ `uppercase`؟ `first_uppercase`؟ `capitalize`؟ +بعد، با دوست قدیمی برنامه‌نویسا، تکمیل خودکار ویرایشگر، امتحان می‌کنی. -اینجاست که سراغ دوست قدیمی برنامه‌نویس‌ها، یعنی **تکمیل خودکار** ادیتور می‌روید. +پارامتر اول تابع، `first_name` رو تایپ می‌کنی، بعد یه نقطه (`.`) می‌ذاری و `Ctrl+Space` رو می‌زنی تا تکمیل خودکار بیاد. -پارامتر اول تابع (`first_name`) را تایپ می‌کنید، یک نقطه (`.`) می‌گذارید و `Ctrl+Space` را فشار می‌دهید تا تکمیل خودکار فعال شود. +ولی متأسفانه، چیز مفیدی نمی‌گیری: -اما متأسفانه چیزی مفید نمایش داده نمی‌شود: + -### افزودن نوع (Add types) +### نوع اضافه کن -بیایید یک خط از نسخه‌ی قبلی را تغییر دهیم. بخش پارامترهای تابع را از: +بیا فقط یه خط از نسخه قبلی رو تغییر بدیم. + +دقیقاً این بخش، پارامترهای تابع رو، از: ```Python first_name, last_name ``` -به این تغییر می‌دهیم: +به: ```Python first_name: str, last_name: str ``` -این همان **نشانه‌های نوع** است: +عوض می‌کنیم. -{\* ../../docs\_src/python\_types/tutorial002.py hl[1] \*} +همینه. -این کار با تعریف مقدار پیش‌فرض (مثلاً `first_name="john"`) متفاوت است. ما از دونقطه (`:`) استفاده می‌کنیم، نه مساوی (`=`). +اینا همون "نوع‌نماها" هستن: -افزودن type hints معمولاً رفتار برنامه را تغییر نمی‌دهد. +{* ../../docs_src/python_types/tutorial002.py hl[1] *} -حالا اگر در حال نوشتن همین تابع با type hints باشید و `Ctrl+Space` را فشار دهید، این را مشاهده می‌کنید: +این با تعریف مقدار پیش‌فرض فرق داره، مثل: -اکنون می‌توانید گزینه‌های صحیح را سریع‌تر پیدا کنید: +```Python + first_name="john", last_name="doe" +``` -## انگیزه‌ی بیشتر (More Motivation) +یه چیز متفاوته. -این تابع که از قبل type hints دارد را بررسی کنید: +ما از دونقطه (`:`) استفاده می‌کنیم، نه علامت مساوی (`=`)‌. -{\* ../../docs\_src/python\_types/tutorial003.py hl[1] \*} +و اضافه کردن نوع‌نماها معمولاً چیزی که اتفاق می‌افته رو از چیزی که بدون اونا می‌افتاد تغییر نمی‌ده. -از آنجا که ادیتور نوع متغیرها را می‌داند، نه تنها **تکمیل خودکار**، بلکه **بررسی خطاها** نیز انجام می‌شود: +ولی حالا، دوباره تصور کن وسط ساختن اون تابع هستی، ولی این بار با نوع‌نماها. -حالا متوجه می‌شوید که باید `age` را با `str(age)` به رشته تبدیل کنید: +توی همون نقطه، سعی می‌کنی تکمیل خودکار رو با `Ctrl+Space` فعال کنی و اینو می‌بینی: -{\* ../../docs\_src/python\_types/tutorial004.py hl[2] \*} + -## اعلام انواع (Declaring Types) +با این، می‌تونی اسکرول کنی، گزینه‌ها رو ببینی، تا وقتی که اون چیزی که "به نظرت آشنا میاد" رو پیدا کنی: -### انواع ساده (Simple Types) + -می‌توانید از انواع استاندارد پایتون مانند `int`، `float`، `bool` و `bytes` استفاده کنید: +## انگیزه بیشتر -{\* ../../docs\_src/python\_types/tutorial005.py hl[1] \*} +این تابع رو چک کن، الان نوع‌نما داره: -### انواع جنریک با پارامترهای نوع (Generic Types) +{* ../../docs_src/python_types/tutorial003.py hl[1] *} -ساختارهای داده‌ای مانند `list`، `dict`، `set` و `tuple` که می‌توانند شامل مقادیر دیگر باشند، «جنریک» نامیده می‌شوند. برای تعیین نوع داخلی آن‌ها از ماژول `typing` استفاده می‌شود. +چون ویرایشگر نوع متغیرها رو می‌دونه، فقط تکمیل خودکار نمی‌گیری، بلکه چک خطاها هم داری: -#### نسخه‌های جدید پایتون + -در نسخه‌های جدید پایتون (مثلاً ۳.۹+)، می‌توانید به جای `List` از `list` استفاده کنید: +حالا می‌دونی که باید درستش کنی، `age` رو با `str(age)` به یه رشته تبدیل کنی: -```Python -def process_items(items: list[str]): - for item in items: - print(item) -``` +{* ../../docs_src/python_types/tutorial004.py hl[2] *} + +## تعریف نوع‌ها + +تازه اصلی‌ترین جا برای تعریف نوع‌نماها رو دیدی. به‌عنوان پارامترهای تابع. + +این هم اصلی‌ترین جاییه که با **FastAPI** ازشون استفاده می‌کنی. + +### نوع‌های ساده + +می‌تونی همه نوع‌های استاندارد پایتون رو تعریف کنی، نه فقط `str`. + +مثلاً می‌تونی از اینا استفاده کنی: + +* `int` +* `float` +* `bool` +* `bytes` + +{* ../../docs_src/python_types/tutorial005.py hl[1] *} + +### نوع‌های عمومی با پارامترهای نوع + +یه سری ساختار داده هستن که می‌تونن مقدارهای دیگه رو نگه دارن، مثل `dict`، `list`، `set` و `tuple`. و مقدارهای داخلیشون هم می‌تونن نوع خودشون رو داشته باشن. + +به این نوع‌ها که نوع‌های داخلی دارن می‌گن "**عمومی**" یا "generic". و می‌شه اونا رو تعریف کرد، حتی با نوع‌های داخلیشون. + +برای تعریف این نوع‌ها و نوع‌های داخلیشون، می‌تونی از ماژول استاندارد پایتون `typing` استفاده کنی. این ماژول مخصوص پشتیبانی از نوع‌نماهاست. + +#### نسخه‌های جدیدتر پایتون + +سینتکس با استفاده از `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+**". + +#### لیست -#### لیست (List) +مثلاً، بیایم یه متغیر تعریف کنیم که یه `list` از `str` باشه. //// tab | Python 3.9+ -```Python +متغیر رو با همون سینتکس دونقطه (`:`) تعریف کن. + +به‌عنوان نوع، `list` رو بذار. + +چون لیست یه نوعه که نوع‌های داخلی داره، اونا رو توی کروشه‌ها می‌ذاری: + +```Python hl_lines="1" {!> ../../docs_src/python_types/tutorial006_py39.py!} ``` //// -#### تاپل و ست (Tuple and Set) +//// tab | Python 3.8+ + +از `typing`، `List` رو (با `L` بزرگ) وارد کن: + +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial006.py!} +``` + +متغیر رو با همون سینتکس دونقطه (`:`) تعریف کن. + +به‌عنوان نوع، `List` رو که از `typing` وارد کردی بذار. + +چون لیست یه نوعه که نوع‌های داخلی داره، اونا رو توی کروشه‌ها می‌ذاری: + +```Python hl_lines="4" +{!> ../../docs_src/python_types/tutorial006.py!} +``` + +//// + +/// info + +اون نوع‌های داخلی توی کروشه‌ها بهشون "پارامترهای نوع" می‌گن. + +توی این مورد، `str` پارامتر نوعیه که به `List` (یا `list` توی پایتون 3.9 و بالاتر) پاس داده شده. + +/// + +یعنی: "متغیر `items` یه `list` هست، و هر کدوم از آیتم‌های این لیست یه `str` هستن". + +/// tip + +اگه از پایتون 3.9 یا بالاتر استفاده می‌کنی، لازم نیست `List` رو از `typing` وارد کنی، می‌تونی همون نوع معمولی `list` رو به جاش استفاده کنی. + +/// + +با این کار، ویرایشگرت حتی وقتی داری آیتم‌های لیست رو پردازش می‌کنی بهت کمک می‌کنه: + + + +بدون نوع‌ها، رسیدن به این تقریباً غیرممکنه. + +توجه کن که متغیر `item` یکی از عناصر توی لیست `items` هست. + +و با این حال، ویرایشگر می‌دونه که یه `str` هست و براش پشتیبانی می‌ده. + +#### تاپل و ست + +برای تعریف `tuple`ها و `set`ها هم همین کار رو می‌کنی: //// tab | Python 3.9+ -```Python +```Python hl_lines="1" {!> ../../docs_src/python_types/tutorial007_py39.py!} ``` //// -#### دیکشنری (Dict) +//// tab | Python 3.8+ + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial007.py!} +``` + +//// + +یعنی: + +* متغیر `items_t` یه `tuple` با 3 تا آیتمه، یه `int`، یه `int` دیگه، و یه `str`. +* متغیر `items_s` یه `set` هست، و هر کدوم از آیتم‌هاش از نوع `bytes` هستن. + +#### دیکشنری + +برای تعریف یه `dict`، 2 تا پارامتر نوع می‌دی، که با کاما از هم جدا شدن. + +پارامتر نوع اول برای کلیدهای `dict` هست. + +پارامتر نوع دوم برای مقدارهای `dict` هست: //// tab | Python 3.9+ -```Python +```Python hl_lines="1" {!> ../../docs_src/python_types/tutorial008_py39.py!} ``` //// -#### یونیون (Union) +//// tab | Python 3.8+ -در پایتون ۳.۱۰+ می‌توانید از سینتکس `|` استفاده کنید: +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial008.py!} +``` + +//// + +یعنی: + +* متغیر `prices` یه `dict` هست: + * کلیدهای این `dict` از نوع `str` هستن (مثلاً اسم هر آیتم). + * مقدارهای این `dict` از نوع `float` هستن (مثلاً قیمت هر آیتم). + +#### اتحادیه + +می‌تونی تعریف کنی که یه متغیر می‌تونه هر کدوم از **چند تا نوع** باشه، مثلاً یه `int` یا یه `str`. + +توی پایتون 3.6 و بالاتر (از جمله پایتون 3.10) می‌تونی از نوع `Union` توی `typing` استفاده کنی و نوع‌های ممکن رو توی کروشه‌ها بذاری. + +توی پایتون 3.10 یه **سینتکس جدید** هم هست که می‌تونی نوع‌های ممکن رو با یه خط عمودی (`|`) جدا کنی. //// tab | Python 3.10+ -```Python +```Python hl_lines="1" {!> ../../docs_src/python_types/tutorial008b_py310.py!} ``` //// -#### مقادیر اختیاری (Optional) +//// tab | Python 3.8+ + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial008b.py!} +``` + +//// + +توی هر دو حالت یعنی `item` می‌تونه یه `int` یا یه `str` باشه. + +#### شاید `None` + +می‌تونی تعریف کنی که یه مقدار می‌تونه یه نوع باشه، مثلاً `str`، ولی می‌تونه `None` هم باشه. + +توی پایتون 3.6 و بالاتر (از جمله پایتون 3.10) می‌تونی با وارد کردن و استفاده از `Optional` از ماژول `typing` اینو تعریف کنی. + +```Python hl_lines="1 4" +{!../../docs_src/python_types/tutorial009.py!} +``` + +استفاده از `Optional[str]` به جای فقط `str` به ویرایشگر کمک می‌کنه خطاهایی که ممکنه فکر کنی یه مقدار همیشه `str` هست رو پیدا کنه، در حالی که می‌تونه `None` هم باشه. + +`Optional[Something]` در واقع میان‌بر برای `Union[Something, None]` هست، این دو تا معادلن. + +یعنی توی پایتون 3.10، می‌تونی از `Something | None` استفاده کنی: + +//// tab | Python 3.10+ + +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial009_py310.py!} +``` + +//// + +//// tab | Python 3.8+ + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial009.py!} +``` + +//// + +//// tab | Python 3.8+ جایگزین + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial009b.py!} +``` + +//// + +#### استفاده از `Union` یا `Optional` + +اگه از نسخه پایتون زیر 3.10 استفاده می‌کنی، یه note از دید خیلی **شخصی** خودم: + +* 🚨 از `Optional[SomeType]` استفاده نکن +* به جاش ✨ **از `Union[SomeType, None]` استفاده کن** ✨. + +هر دو معادلن و زیر پوسته یکی‌ان، ولی من `Union` رو به `Optional` ترجیح می‌دم چون کلمه "**اختیاری**" انگار暗示 می‌کنه که مقدار اختیاریه، در حالی که در واقع یعنی "می‌تونه `None` باشه"، حتی اگه اختیاری نباشه و هنوز لازم باشه. + +فکر می‌کنم `Union[SomeType, None]` واضح‌تر نشون می‌ده چی معنی می‌ده. + +فقط بحث کلمات و اسم‌هاست. ولی این کلمات می‌تونن رو طرز فکر تو و تیمت نسبت به کد تأثیر بذارن. + +به‌عنوان مثال، این تابع رو ببین: + +{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} + +پارامتر `name` به‌عنوان `Optional[str]` تعریف شده، ولی **اختیاری نیست**، نمی‌تونی تابع رو بدون پارامتر صدا کنی: + +```Python +say_hi() # اوه نه، این خطا می‌ده! 😱 +``` + +پارامتر `name` **هنوز لازمه** (نه *اختیاری*) چون مقدار پیش‌فرض نداره. با این حال، `name` مقدار `None` رو قبول می‌کنه: + +```Python +say_hi(name=None) # این کار می‌کنه، None معتبره 🎉 +``` + +خبر خوب اینه که وقتی رو پایتون 3.10 باشی، لازم نیست نگران این باشی، چون می‌تونی به‌سادگی از `|` برای تعریف اتحادیه نوع‌ها استفاده کنی: + +{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *} + +اون موقع دیگه لازم نیست نگران اسم‌هایی مثل `Optional` و `Union` باشی. 😎 + +#### نوع‌های عمومی + +این نوع‌هایی که پارامترهای نوع رو توی کروشه‌ها می‌گیرن بهشون **نوع‌های عمومی** یا **Generics** می‌گن، مثلاً: + +//// tab | Python 3.10+ + +می‌تونی از همون نوع‌های داخلی به‌عنوان نوع‌های عمومی استفاده کنی (با کروشه‌ها و نوع‌ها داخلشون): + +* `list` +* `tuple` +* `set` +* `dict` + +و همون‌طور که توی پایتون 3.8 بود، از ماژول `typing`: + +* `Union` +* `Optional` (همون‌طور که توی پایتون 3.8 بود) +* ...و بقیه. + +توی پایتون 3.10، به‌عنوان جایگزین برای استفاده از نوع‌های عمومی `Union` و `Optional`، می‌تونی از خط عمودی (`|`) برای تعریف اتحادیه نوع‌ها استفاده کنی، که خیلی بهتر و ساده‌تره. + +//// + +//// tab | Python 3.9+ + +می‌تونی از همون نوع‌های داخلی به‌عنوان نوع‌های عمومی استفاده کنی (با کروشه‌ها و نوع‌ها داخلشون): + +* `list` +* `tuple` +* `set` +* `dict` + +و همون‌طور که توی پایتون 3.8 بود، از ماژول `typing`: + +* `Union` +* `Optional` +* ...و بقیه. + +//// + +//// tab | Python 3.8+ + +* `List` +* `Tuple` +* `Set` +* `Dict` +* `Union` +* `Optional` +* ...و بقیه. + +//// + +### کلاس‌ها به‌عنوان نوع + +می‌تونی یه کلاس رو هم به‌عنوان نوع یه متغیر تعریف کنی. + +فرض کن یه کلاس `Person` داری، با یه نام: + +{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} + +بعد می‌تونی یه متغیر رو از نوع `Person` تعریف کنی: + +{* ../../docs_src/python_types/tutorial010.py hl[6] *} + +و بعد، دوباره، همه پشتیبانی ویرایشگر رو داری: + + + +توجه کن که این یعنی "`one_person` یه **نمونه** از کلاس `Person` هست". + +یعنی "`one_person` خود **کلاس** به اسم `Person` نیست". + +## مدل‌های Pydantic + +Pydantic یه کتابخونه پایتونه برای اعتبارسنجی داده‌ها. + +"شکل" داده‌ها رو به‌عنوان کلاس‌هایی با ویژگی‌ها تعریف می‌کنی. + +و هر ویژگی یه نوع داره. + +بعد یه نمونه از اون کلاس رو با یه سری مقدار می‌سازی و اون مقدارها رو اعتبارسنجی می‌کنه، به نوع مناسب تبدیلشون می‌کنه (اگه لازم باشه) و یه شیء با همه داده‌ها بهت می‌ده. + +و با اون شیء نهایی همه پشتیبانی ویرایشگر رو می‌گیری. + +یه مثال از مستندات رسمی Pydantic: + +//// tab | Python 3.10+ + +```Python +{!> ../../docs_src/python_types/tutorial011_py310.py!} +``` + +//// + +//// tab | Python 3.9+ ```Python -from typing import Optional +{!> ../../docs_src/python_types/tutorial011_py39.py!} +``` + +//// + +//// tab | Python 3.8+ -def say_hi(name: Optional[str] = None): - if name is not None: - print(f"Hey {name}!") - else: - print("Hello World") +```Python +{!> ../../docs_src/python_types/tutorial011.py!} ``` -## نوعدهی در FastAPI +//// + +/// info + +برای info بیشتر در مورد Pydantic، مستنداتش رو چک کن. + +/// + +**FastAPI** کاملاً بر پایه Pydantic هست. + +توی [آموزش - راهنمای کاربر](tutorial/index.md){.internal-link target=_blank} خیلی بیشتر از اینا رو توی عمل می‌بینی. + +/// tip + +Pydantic یه رفتار خاص داره وقتی از `Optional` یا `Union[Something, None]` بدون مقدار پیش‌فرض استفاده می‌کنی، می‌تونی توی مستندات Pydantic در مورد فیلدهای اختیاری لازم بیشتر بخونی. + +/// + +## نوع‌نماها با Annotationهای متادیتا + +پایتون یه قابلیت هم داره که بهت اجازه می‌ده **متادیتا اضافی** رو توی این نوع‌نماها بذاری با استفاده از `Annotated`. + +//// tab | Python 3.9+ + +توی پایتون 3.9، `Annotated` بخشی از کتابخونه استاندارده، پس می‌تونی از `typing` واردش کنی. + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial013_py39.py!} +``` + +//// + +//// tab | Python 3.8+ + +توی نسخه‌های زیر پایتون 3.9، `Annotated` رو از `typing_extensions` وارد می‌کنی. + +با **FastAPI** از قبل نصب شده. + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial013.py!} +``` + +//// + +خود پایتون با این `Annotated` کاری نمی‌کنه. و برای ویرایشگرها و ابزارهای دیگه، نوع هنوز `str` هست. + +ولی می‌تونی از این فضا توی `Annotated` استفاده کنی تا به **FastAPI** متادیتای اضافی در مورد اینکه چطور می‌خوای برنامه‌ات رفتار کنه بدی. + +note مهم اینه که **اولین *پارامتر نوع*** که به `Annotated` می‌دی، **نوع واقعی** هست. بقیش فقط متادیتا برای ابزارهای دیگه‌ست. + +الان فقط باید بدونی که `Annotated` وجود داره، و اینکه پایتون استاندارده. 😎 + +بعداً می‌بینی که چقدر **قوی** می‌تونه باشه. + +/// tip + +اینکه این **پایتون استاندارده** یعنی هنوز **بهترین تجربه توسعه‌دهنده** رو توی ویرایشگرت، با ابزارهایی که برای تحلیل و بازسازی کدت استفاده می‌کنی و غیره می‌گیری. ✨ + +و همین‌طور کدت با خیلی از ابزارها و کتابخونه‌های دیگه پایتون خیلی سازگار می‌مونه. 🚀 + +/// + +## نوع‌نماها توی **FastAPI** + +**FastAPI** از این نوع‌نماها استفاده می‌کنه تا چند تا کار بکنه. + +با **FastAPI** پارامترها رو با نوع‌نماها تعریف می‌کنی و اینا رو می‌گیری: + +* **پشتیبانی ویرایشگر**. +* **چک نوع‌ها**. + +...و **FastAPI** از همون تعریف‌ها برای اینا استفاده می‌کنه: + +* **تعریف نیازها**: از پارامترهای مسیر درخواست، پارامترهای کوئری، هدرها، بدنه‌ها، وابستگی‌ها و غیره. +* **تبدیل داده**: از درخواست به نوع مورد نیاز. +* **اعتبارسنجی داده**: که از هر درخواست میاد: + * تولید **خطاهای خودکار** که به کلاینت برمی‌گرده وقتی داده نامعتبره. +* **مستندسازی** API با استفاده از OpenAPI: + * که بعدش توسط رابط‌های کاربری مستندات تعاملی خودکار استفاده می‌شه. + +اینا شاید همه‌ش انتزاعی به نظر بیاد. نگران نباش. همه اینا رو توی عمل توی [آموزش - راهنمای کاربر](tutorial/index.md){.internal-link target=_blank} می‌بینی. -‏FastAPI از type hints برای: +note مهم اینه که با استفاده از نوع‌های استاندارد پایتون، توی یه جا (به جای اضافه کردن کلاس‌های بیشتر، دکوراتورها و غیره)، **FastAPI** کلی از کار رو برات انجام می‌ده. -- دریافت خودکار پارامترها -- تبدیل داده‌ها -- اعتبارسنجی -- تولید مستندات OpenAPI +/// info -استفاده می‌کند. +اگه همه آموزش رو گذروندی و برگشتی که بیشتر در مورد نوع‌ها ببینی، یه منبع خوب "تقلب‌نامه" از `mypy` هست. -/// اطلاعات -اگر همه‌ی آموزش را گذرانده‌اید و بازگشته‌اید تا اطلاعات بیشتری درباره‌ی انواع داده به دست آورید، یک منبع خوب "cheat sheet" از mypy است. ///