From 0308a6f517dff17afa56abed0f9c6f1d1aa4ce55 Mon Sep 17 00:00:00 2001
From: Mohammad <116789737+Mohammad222PR@users.noreply.github.com>
Date: Mon, 17 Mar 2025 23:52:24 +0330
Subject: [PATCH] refactor: update text tone
---
docs/fa/python-types.md | 552 ++++++++++++++++++++++++++++++++++------
1 file changed, 473 insertions(+), 79 deletions(-)
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 است.
///