From 9015240b5e51a7cf7d5b545101b47080d5df3627 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 23 Mar 2026 05:15:01 +0000 Subject: [PATCH 1/4] Update translation: lectures/pandas.md --- lectures/pandas.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lectures/pandas.md b/lectures/pandas.md index d37b025..f4825d2 100644 --- a/lectures/pandas.md +++ b/lectures/pandas.md @@ -10,6 +10,7 @@ kernelspec: language: python name: python3 heading-map: + '{index}`Pandas `': '{index}`Pandas `' Overview: مرور کلی Series: Series DataFrames: DataFrames @@ -35,6 +36,17 @@ heading-map: # {index}`Pandas ` +(pd)= +```{raw} jupyter + +``` + +# {index}`Pandas ` + ```{index} single: Python; Pandas ``` @@ -172,7 +184,7 @@ s ما این را از یک URL با استفاده از تابع `read_csv` در `pandas` خواهیم خواند. ```{code-cell} ipython3 -df = pd.read_csv('https://raw.githubusercontent.com/QuantEcon/lecture-python-programming/master/source/_static/lecture_specific/pandas/data/test_pwt.csv') +df = pd.read_csv('https://raw.githubusercontent.com/QuantEcon/lecture-python-programming/main/lectures/_static/lecture_specific/pandas/data/test_pwt.csv') type(df) ``` @@ -806,4 +818,4 @@ plt.tight_layout() ```{solution-end} ``` -[^mung]: ویکی‌پدیا munging را به عنوان پاک‌سازی داده از یک فرم خام به یک فرم ساختاریافته و تصفیه شده تعریف می‌کند. \ No newline at end of file +[^mung]: ویکی‌پدیا munging را به عنوان پاک‌سازی داده از یک فرم خام به یک فرم ساختاریافته و تصفیه شده تعریف می‌کند. From 4bf575420a96cec2b2735e4e160cb4dcc2eb074d Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 23 Mar 2026 05:15:04 +0000 Subject: [PATCH 2/4] Update translation: .translate/state/pandas.md.yml --- .translate/state/pandas.md.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.translate/state/pandas.md.yml b/.translate/state/pandas.md.yml index cf604aa..7f84532 100644 --- a/.translate/state/pandas.md.yml +++ b/.translate/state/pandas.md.yml @@ -1,6 +1,6 @@ -source-sha: 9490497982787a5b0eb54ee1dcd73ac326d5ae04 -synced-at: "2026-03-20" -model: unknown -mode: RESYNC +source-sha: 02e57a5befc2a9a081019edc748aba15e4b2f02a +synced-at: "2026-03-23" +model: claude-sonnet-4-6 +mode: UPDATE section-count: 5 -tool-version: 0.11.0 +tool-version: 0.11.2 From 501bf2e386d966debeb15fe3d2b68e6d033b2737 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 23 Mar 2026 05:15:07 +0000 Subject: [PATCH 3/4] Update translation: lectures/python_advanced_features.md --- lectures/python_advanced_features.md | 451 +++++++++++++++++---------- 1 file changed, 281 insertions(+), 170 deletions(-) diff --git a/lectures/python_advanced_features.md b/lectures/python_advanced_features.md index 2633664..9f5dde2 100644 --- a/lectures/python_advanced_features.md +++ b/lectures/python_advanced_features.md @@ -8,29 +8,36 @@ kernelspec: language: python name: python3 heading-map: + More Language Features: ویژگی‌های بیشتر زبان Overview: مروری کلی - Iterables and Iterators: Iterableها و Iteratorها - Iterables and Iterators::Iterators: Iteratorها - Iterables and Iterators::Iterators in For Loops: Iteratorها در حلقه‌های For - Iterables and Iterators::Iterables: Iterableها - Iterables and Iterators::Iterators and built-ins: Iteratorها و توابع داخلی - '`*` and `**` Operators': عملگرهای `*` و `**` - '`*` and `**` Operators::Unpacking Arguments': باز کردن آرگومان‌ها - '`*` and `**` Operators::Arbitrary Arguments': آرگومان‌های دلخواه - Decorators and Descriptors: Decoratorها و Descriptorها - Decorators and Descriptors::Decorators: Decoratorها - Decorators and Descriptors::Decorators::An Example: یک مثال - Decorators and Descriptors::Decorators::Enter Decorators: Decoratorها وارد می‌شوند - Decorators and Descriptors::Descriptors: Descriptorها - Decorators and Descriptors::Descriptors::A Solution: یک راه‌حل - Decorators and Descriptors::Descriptors::How it Works: چگونه کار می‌کند - Decorators and Descriptors::Descriptors::Decorators and Properties: Decoratorها و Propertyها + Iterables and iterators: تکرارپذیرها و تکرارکننده‌ها + Iterables and iterators::Iterators: تکرارکننده‌ها + Iterables and iterators::Iterators in for loops: تکرارکننده‌ها در حلقه‌های for + Iterables and iterators::Iterables: تکرارپذیرها + Iterables and iterators::Iterators and built-ins: تکرارکننده‌ها و توابع توکار + '`*` and `**` operators': عملگرهای `*` و `**` + '`*` and `**` operators::Unpacking arguments': باز کردن آرگومان‌ها + '`*` and `**` operators::Arbitrary arguments': آرگومان‌های دلخواه + Type hints: راهنمای نوع + Type hints::Basic syntax: نحو پایه + Type hints::Common types: نوع‌های رایج + Type hints::Hints don't enforce types: راهنماها نوع را اعمال نمی‌کنند + Type hints::Why use type hints?: چرا از راهنمای نوع استفاده کنیم؟ + Type hints::Type hints in scientific Python: راهنمای نوع در Python علمی + Decorators and descriptors: دکوراتورها و توصیف‌گرها + Decorators and descriptors::Decorators: دکوراتورها + Decorators and descriptors::Decorators::An example: یک مثال + Decorators and descriptors::Decorators::Enter decorators: ورود دکوراتورها + Decorators and descriptors::Descriptors: توصیف‌گرها + Decorators and descriptors::Descriptors::A solution: یک راه‌حل + Decorators and descriptors::Descriptors::How it works: چگونگی کارکرد آن + Decorators and descriptors::Descriptors::Decorators and properties: دکوراتورها و ویژگی‌ها Generators: Generatorها - Generators::Generator Expressions: عبارات Generator - Generators::Generator Functions: توابع Generator - Generators::Generator Functions::Example 1: مثال 1 - Generators::Generator Functions::Example 2: مثال 2 - Generators::Advantages of Iterators: مزایای Iteratorها + Generators::Generator expressions: عبارات Generator + Generators::Generator functions: توابع Generator + Generators::Generator functions::Example 1: مثال 1 + Generators::Generator functions::Example 2: مثال 2 + Generators::Advantages of iterators: مزایای Iteratorها Exercises: تمرین‌ها --- @@ -45,6 +52,17 @@ heading-map: # ویژگی‌های بیشتر زبان +(python_advanced_features)= +```{raw} jupyter + +``` + +# ویژگی‌های بیشتر زبان + ## مروری کلی توصیه ما برای این سخنرانی آخر این است که **در مرور اول آن را رد کنید**، مگر اینکه میل شدیدی به خواندن آن داشته باشید. @@ -56,31 +74,32 @@ heading-map: موضوعات متنوعی در این سخنرانی بررسی می‌شوند، از جمله iteratorها، decoratorها و descriptorها، و generatorها. -## Iterableها و Iteratorها +## تکرارپذیرها و تکرارکننده‌ها ```{index} single: Python; Iteration ``` -ما قبلاً {ref}`چیزهایی درباره تکرار ` در Python گفته‌ایم. +ما {ref}`قبلاً چیزهایی ` درباره تکرار در Python گفته‌ایم. -اکنون بیایید دقیق‌تر به نحوه کار آن نگاه کنیم، با تمرکز بر پیاده‌سازی Python از حلقه `for`. +حالا بیایید نگاه دقیق‌تری به نحوه عملکرد آن داشته باشیم و بر پیاده‌سازی حلقه `for` در Python تمرکز کنیم. (iterators)= -### Iteratorها + +### تکرارکننده‌ها ```{index} single: Python; Iterators ``` -Iteratorها یک رابط یکنواخت برای حرکت در عناصر یک مجموعه هستند. +تکرارکننده‌ها یک رابط یکنواخت برای گام برداشتن از میان عناصر یک مجموعه هستند. -در اینجا درباره استفاده از iteratorها صحبت خواهیم کرد --- بعداً یاد خواهیم گرفت که چگونه iteratorهای خود را بسازیم. +در اینجا درباره استفاده از تکرارکننده‌ها صحبت خواهیم کرد --- بعداً یاد می‌گیریم چگونه تکرارکننده‌های خود را بسازیم. -به طور رسمی، یک *iterator* یک شیء با متد `__next__` است. +به طور رسمی، یک *تکرارکننده* شیئی است که دارای متد `__next__` است. -به عنوان مثال، اشیاء فایل iterator هستند. +به عنوان مثال، اشیاء فایل تکرارکننده هستند. -برای دیدن این موضوع، بیایید دوباره به {ref}`داده‌های شهرهای آمریکا ` نگاه کنیم، -که در سلول زیر در دایرکتوری کاری فعلی نوشته شده است +برای مشاهده این موضوع، بیایید نگاه دیگری به {ref}`داده‌های شهرهای آمریکا ` داشته باشیم، +که در سلول زیر در پوشه کاری جاری نوشته می‌شود ```{code-cell} ipython %%file us_cities.txt @@ -104,16 +123,16 @@ f.__next__() f.__next__() ``` -می‌بینیم که اشیاء فایل واقعاً یک متد `__next__` دارند و فراخوانی این متد خط بعدی فایل را برمی‌گرداند. +می‌بینیم که اشیاء فایل واقعاً دارای متد `__next__` هستند و فراخوانی این متد خط بعدی فایل را برمی‌گرداند. -متد next همچنین می‌تواند از طریق تابع داخلی `next()` قابل دسترسی باشد، +متد next همچنین از طریق تابع توکار `next()` نیز قابل دسترسی است، که مستقیماً این متد را فراخوانی می‌کند ```{code-cell} python3 next(f) ``` -اشیاء بازگردانده شده توسط `enumerate()` نیز iterator هستند +اشیاء بازگردانده‌شده توسط `enumerate()` نیز تکرارکننده هستند ```{code-cell} python3 e = enumerate(['foo', 'bar']) @@ -124,9 +143,9 @@ next(e) next(e) ``` -همچنین اشیاء reader از ماژول `csv`. +اشیاء reader از ماژول `csv` نیز همین‌طور هستند. -بیایید یک فایل csv کوچک بسازیم که داده‌هایی از شاخص NIKKEI را در خود دارد +بیایید یک فایل csv کوچک حاوی داده‌های شاخص NIKKEI بسازیم ```{code-cell} ipython %%file test_table.csv @@ -155,14 +174,14 @@ next(nikkei_data) next(nikkei_data) ``` -### Iteratorها در حلقه‌های For +### تکرارکننده‌ها در حلقه‌های for ```{index} single: Python; Iterators ``` -همه iteratorها می‌توانند در سمت راست کلمه کلیدی `in` در دستورات حلقه `for` قرار گیرند. +تمام تکرارکننده‌ها می‌توانند در سمت راست کلیدواژه `in` در دستورات حلقه `for` قرار گیرند. -در واقع به این ترتیب است که حلقه `for` کار می‌کند: اگر بنویسیم +در واقع حلقه `for` به همین شکل کار می‌کند: اگر بنویسیم ```{code-block} python3 :class: no-execute @@ -175,9 +194,9 @@ for x in iterator: * `iterator.___next___()` را فراخوانی می‌کند و `x` را به نتیجه متصل می‌کند * بلوک کد را اجرا می‌کند -* تکرار می‌کند تا خطای `StopIteration` رخ دهد +* تا زمانی که خطای `StopIteration` رخ دهد تکرار می‌کند -بنابراین اکنون می‌دانید که این نحو جادویی چگونه کار می‌کند +پس حالا می‌دانید این نحو جادویی چگونه کار می‌کند ```{code-block} python3 :class: no-execute @@ -187,28 +206,28 @@ for line in f: # do something ``` -مفسر فقط ادامه می‌دهد +مفسر فقط به طور مداوم -1. فراخوانی `f.__next__()` و اتصال `line` به نتیجه -1. اجرای بدنه حلقه +1. `f.__next__()` را فراخوانی می‌کند و `line` را به نتیجه متصل می‌کند +1. بدنه حلقه را اجرا می‌کند -این کار تا زمانی که خطای `StopIteration` رخ دهد، ادامه دارد. +این تا زمان وقوع خطای `StopIteration` ادامه می‌یابد. -### Iterableها +### تکرارپذیرها ```{index} single: Python; Iterables ``` -شما از قبل می‌دانید که می‌توانیم یک لیست Python را در سمت راست `in` در یک حلقه `for` قرار دهیم +شما از قبل می‌دانید که می‌توانیم یک لیست Python را در سمت راست `in` در حلقه `for` قرار دهیم ```{code-cell} python3 for i in ['spam', 'eggs']: print(i) ``` -پس آیا این یعنی که لیست یک iterator است؟ +پس آیا این به این معنی است که یک لیست تکرارکننده است؟ -جواب منفی است +پاسخ خیر است ```{code-cell} python3 x = ['foo', 'bar'] @@ -222,11 +241,11 @@ tags: [raises-exception] next(x) ``` -پس چرا می‌توانیم روی یک لیست در یک حلقه `for` تکرار کنیم؟ +پس چرا می‌توانیم روی یک لیست در حلقه `for` تکرار کنیم؟ -دلیل این است که یک لیست *iterable* است (در مقابل یک iterator). +دلیل این است که یک لیست *تکرارپذیر* است (در مقابل تکرارکننده). -به طور رسمی، یک شیء iterable است اگر بتواند با استفاده از تابع داخلی `iter()` به یک iterator تبدیل شود. +به طور رسمی، یک شیء تکرارپذیر است اگر بتوان آن را با استفاده از تابع توکار `iter()` به تکرارکننده تبدیل کرد. لیست‌ها یکی از این اشیاء هستند @@ -255,9 +274,9 @@ tags: [raises-exception] next(y) ``` -بسیاری از اشیاء دیگر نیز iterable هستند، مانند دیکشنری‌ها و tupleها. +بسیاری از اشیاء دیگر نیز تکرارپذیر هستند، مانند دیکشنری‌ها و تاپل‌ها. -البته، همه اشیاء iterable نیستند +البته، همه اشیاء تکرارپذیر نیستند ```{code-cell} python3 --- @@ -266,19 +285,19 @@ tags: [raises-exception] iter(42) ``` -برای نتیجه‌گیری از بحث ما درباره حلقه‌های `for` +برای جمع‌بندی بحث ما درباره حلقه‌های `for` -* حلقه‌های `for` روی iteratorها یا iterableها کار می‌کنند. -* در حالت دوم، iterable قبل از شروع حلقه به یک iterator تبدیل می‌شود. +* حلقه‌های `for` روی تکرارکننده‌ها یا تکرارپذیرها کار می‌کنند. +* در حالت دوم، تکرارپذیر قبل از شروع حلقه به تکرارکننده تبدیل می‌شود. -### Iteratorها و توابع داخلی +### تکرارکننده‌ها و توابع توکار ```{index} single: Python; Iterators ``` -برخی از توابع داخلی که روی توالی‌ها عمل می‌کنند، با iterableها نیز کار می‌کنند +برخی از توابع توکار که روی دنباله‌ها عمل می‌کنند با تکرارپذیرها نیز کار می‌کنند -* `max()`، `min()`، `sum()`، `all()`، `any()` +* `max()`, `min()`, `sum()`, `all()`, `any()` به عنوان مثال @@ -296,7 +315,7 @@ type(y) max(y) ``` -یک نکته که باید درباره iteratorها به خاطر بسپارید این است که آن‌ها با استفاده مصرف می‌شوند +یک نکته‌ای که باید درباره تکرارکننده‌ها به خاطر بسپارید این است که با استفاده تخلیه می‌شوند ```{code-cell} python3 x = [10, -10] @@ -313,18 +332,17 @@ max(y) ## عملگرهای `*` و `**` -`*` و `**` ابزارهای مناسب و پرکاربردی برای باز کردن لیست‌ها و tupleها و اجازه دادن به کاربران برای تعریف توابعی هستند که تعداد دلخواه آرگومان را به عنوان ورودی می‌گیرند. - -در این بخش، نحوه استفاده از آن‌ها و تمایز موارد استفاده آن‌ها را بررسی خواهیم کرد. +`*` و `**` ابزارهای مفید و پرکاربردی هستند که برای باز کردن لیست‌ها و تاپل‌ها و همچنین برای تعریف توابعی که آرگومان‌های دلخواه را به عنوان ورودی دریافت می‌کنند، به کار می‌روند. +در این بخش، نحوه استفاده از آن‌ها را بررسی کرده و موارد استفاده‌شان را از هم تمیز می‌دهیم. ### باز کردن آرگومان‌ها -وقتی روی لیستی از پارامترها عمل می‌کنیم، اغلب نیاز داریم که محتوای لیست را به عنوان آرگومان‌های منفرد به جای یک مجموعه استخراج کنیم هنگام ارسال آن‌ها به توابع. +هنگامی که با یک لیست از پارامترها کار می‌کنیم، اغلب لازم است محتوای لیست را به جای یک مجموعه، به صورت آرگومان‌های مجزا هنگام ارسال به توابع استخراج کنیم. -خوشبختانه، عملگر `*` می‌تواند به ما کمک کند تا لیست‌ها و tupleها را به [*آرگومان‌های موضعی*](pos_args) در فراخوانی توابع باز کنیم. +خوشبختانه، عملگر `*` می‌تواند به ما کمک کند تا لیست‌ها و تاپل‌ها را به [*آرگومان‌های موضعی*](pos_args) در فراخوانی توابع باز کنیم. -برای مشخص کردن مطلب، مثال‌های زیر را در نظر بگیرید: +برای ملموس‌تر شدن موضوع، مثال‌های زیر را در نظر بگیرید: بدون `*`، تابع `print` یک لیست را چاپ می‌کند @@ -334,19 +352,19 @@ l1 = ['a', 'b', 'c'] print(l1) ``` -در حالی که تابع `print` عناصر منفرد را چاپ می‌کند چون `*` لیست را به آرگومان‌های منفرد باز می‌کند +در حالی که تابع `print` عناصر منفرد را چاپ می‌کند، زیرا `*` لیست را به آرگومان‌های مجزا باز می‌کند ```{code-cell} python3 print(*l1) ``` -باز کردن لیست با استفاده از `*` به آرگومان‌های موضعی معادل تعریف آن‌ها به صورت جداگانه هنگام فراخوانی تابع است +باز کردن لیست با استفاده از `*` به آرگومان‌های موضعی معادل تعریف جداگانه آن‌ها هنگام فراخوانی تابع است ```{code-cell} python3 print('a', 'b', 'c') ``` -با این حال، عملگر `*` راحت‌تر است اگر بخواهیم دوباره از آن‌ها استفاده کنیم +اما عملگر `*` در صورتی که بخواهیم دوباره از آن‌ها استفاده کنیم، راحت‌تر است ```{code-cell} python3 l1.append('d') @@ -356,16 +374,16 @@ print(*l1) به طور مشابه، `**` برای باز کردن آرگومان‌ها استفاده می‌شود. -تفاوت این است که `**` *دیکشنری‌ها* را به *آرگومان‌های کلیدواژه‌ای* باز می‌کند. +تفاوت در این است که `**` *دیکشنری‌ها* را به *آرگومان‌های کلیدواژه‌ای* باز می‌کند. -`**` اغلب زمانی استفاده می‌شود که آرگومان‌های کلیدواژه‌ای زیادی وجود دارد که می‌خواهیم دوباره استفاده کنیم. +`**` اغلب زمانی استفاده می‌شود که آرگومان‌های کلیدواژه‌ای زیادی داریم که می‌خواهیم دوباره از آن‌ها استفاده کنیم. -به عنوان مثال، فرض کنید می‌خواهیم چندین نمودار با استفاده از تنظیمات گرافیکی یکسان رسم کنیم، -که ممکن است شامل تنظیم مکرر بسیاری از پارامترهای گرافیکی باشد که معمولاً با استفاده از آرگومان‌های کلیدواژه‌ای تعریف می‌شوند. +برای مثال، فرض کنید می‌خواهیم چندین نمودار با تنظیمات گرافیکی یکسان رسم کنیم، +که ممکن است شامل تنظیم مکرر پارامترهای گرافیکی زیادی باشد که معمولاً با آرگومان‌های کلیدواژه‌ای تعریف می‌شوند. -در این حالت، می‌توانیم از یک دیکشنری برای ذخیره این پارامترها استفاده کنیم و از `**` برای باز کردن دیکشنری‌ها به آرگومان‌های کلیدواژه‌ای در صورت نیاز استفاده کنیم. +در این حالت، می‌توانیم از یک دیکشنری برای ذخیره این پارامترها استفاده کنیم و از `**` برای باز کردن دیکشنری‌ها به آرگومان‌های کلیدواژه‌ای هنگام نیاز بهره ببریم. -بیایید با هم یک مثال ساده را بررسی کنیم و استفاده از `*` و `**` را متمایز کنیم +بیایید با هم یک مثال ساده را دنبال کنیم و کاربرد `*` و `**` را از هم تمیز دهیم ```{code-cell} python3 import numpy as np @@ -418,30 +436,30 @@ generate_plots(β_0s, β_1s, 1, line_kargs, legend_kargs) plt.show() ``` -در این مثال، `*` پارامترهای zip شده `βs` و خروجی تابع `generate_data` که در tupleها ذخیره شده‌اند را باز کرد، -در حالی که `**` پارامترهای گرافیکی ذخیره شده در `legend_kargs` و `line_kargs` را باز کرد. +در این مثال، `*` پارامترهای زیپ‌شده `βs` و خروجی تابع `generate_data` که در تاپل‌ها ذخیره شده بودند را باز کرد، +در حالی که `**` پارامترهای گرافیکی ذخیره‌شده در `legend_kargs` و `line_kargs` را باز کرد. -برای خلاصه کردن، زمانی که `*list`/`*tuple` و `**dictionary` به *فراخوانی توابع* ارسال می‌شوند، آن‌ها به آرگومان‌های منفرد به جای یک مجموعه باز می‌شوند. +در خلاصه، هنگامی که `*list`/`*tuple` و `**dictionary` به *فراخوانی توابع* ارسال می‌شوند، به جای یک مجموعه، به آرگومان‌های مجزا باز می‌شوند. -تفاوت این است که `*` لیست‌ها و tupleها را به *آرگومان‌های موضعی* باز می‌کند، در حالی که `**` دیکشنری‌ها را به *آرگومان‌های کلیدواژه‌ای* باز می‌کند. +تفاوت در این است که `*` لیست‌ها و تاپل‌ها را به *آرگومان‌های موضعی* باز می‌کند، در حالی که `**` دیکشنری‌ها را به *آرگومان‌های کلیدواژه‌ای* باز می‌کند. ### آرگومان‌های دلخواه -زمانی که توابع را *تعریف* می‌کنیم، گاهی مطلوب است که به کاربران اجازه دهیم هر تعداد آرگومان که می‌خواهند را وارد یک تابع کنند. +هنگامی که توابع را *تعریف* می‌کنیم، گاهی اوقات مطلوب است به کاربران اجازه داده شود هر تعداد آرگومان که می‌خواهند به تابع بدهند. -شاید متوجه شده باشید که تابع `ax.plot()` می‌تواند تعداد دلخواهی آرگومان را مدیریت کند. +شاید متوجه شده باشید که تابع `ax.plot()` می‌تواند با تعداد دلخواه آرگومان کار کند. -اگر به [مستندات](https://github.com/matplotlib/matplotlib/blob/v3.6.2/lib/matplotlib/axes/_axes.py#L1417-L1669) تابع نگاه کنیم، می‌بینیم تابع به صورت زیر تعریف شده است +اگر به [مستندات](https://github.com/matplotlib/matplotlib/blob/v3.6.2/lib/matplotlib/axes/_axes.py#L1417-L1669) تابع نگاه کنیم، می‌بینیم که تابع به صورت زیر تعریف شده است ``` Axes.plot(*args, scalex=True, scaley=True, data=None, **kwargs) ``` -دوباره عملگرهای `*` و `**` را در زمینه *تعریف تابع* یافتیم. +عملگرهای `*` و `**` را دوباره در زمینه *تعریف تابع* مشاهده می‌کنیم. -در واقع، `*args` و `**kargs` در کتابخانه‌های علمی در Python همه جا حضور دارند تا افزونگی را کاهش دهند و ورودی‌های انعطاف‌پذیر را امکان‌پذیر کنند. +در واقع، `*args` و `**kargs` در کتابخانه‌های علمی پایتون برای کاهش تکرار و امکان ورودی‌های انعطاف‌پذیر فراگیر هستند. -`*args` تابع را قادر می‌سازد تا *آرگومان‌های موضعی* با اندازه متغیر را مدیریت کند +`*args` به تابع امکان می‌دهد *آرگومان‌های موضعی* با اندازه متغیر را مدیریت کند ```{code-cell} python3 l1 = ['a', 'b', 'c'] @@ -453,16 +471,16 @@ def arb(*ls): arb(l1, l2) ``` -ورودی‌ها به تابع ارسال شده و در یک tuple ذخیره می‌شوند. +ورودی‌ها به تابع ارسال شده و در یک تاپل ذخیره می‌شوند. -بیایید ورودی‌های بیشتری را امتحان کنیم +بیایید ورودی‌های بیشتری امتحان کنیم ```{code-cell} python3 l3 = ['z', 'x', 'b'] arb(l1, l2, l3) ``` -به طور مشابه، Python به ما اجازه می‌دهد از `**kargs` برای ارسال تعداد دلخواه *آرگومان‌های کلیدواژه‌ای* به توابع استفاده کنیم +به طور مشابه، پایتون به ما اجازه می‌دهد از `**kargs` برای ارسال تعداد دلخواه *آرگومان‌های کلیدواژه‌ای* به توابع استفاده کنیم ```{code-cell} python3 def arb(**ls): @@ -472,19 +490,121 @@ def arb(**ls): arb(l1=l1, l2=l2) ``` -می‌بینیم که Python از یک دیکشنری برای ذخیره این آرگومان‌های کلیدواژه‌ای استفاده می‌کند. +می‌بینیم که پایتون از یک دیکشنری برای ذخیره این آرگومان‌های کلیدواژه‌ای استفاده می‌کند. -بیایید ورودی‌های بیشتری را امتحان کنیم +بیایید ورودی‌های بیشتری امتحان کنیم ```{code-cell} python3 arb(l1=l1, l2=l2, l3=l3) ``` -به طور کلی، `*args` و `**kargs` هنگام *تعریف یک تابع* استفاده می‌شوند؛ آن‌ها تابع را قادر می‌سازند ورودی با اندازه دلخواه بپذیرد. +به طور کلی، `*args` و `**kargs` هنگام *تعریف یک تابع* استفاده می‌شوند؛ آن‌ها به تابع امکان می‌دهند ورودی با اندازه دلخواه دریافت کند. + +تفاوت در این است که توابع با `*args` می‌توانند *آرگومان‌های موضعی* با اندازه دلخواه دریافت کنند، در حالی که `**kargs` به توابع اجازه می‌دهد تعداد دلخواه *آرگومان‌های کلیدواژه‌ای* دریافت کنند. + +## راهنمای نوع + +```{index} single: Python; Type Hints +``` + +Python یک زبان *با نوع‌دهی پویا* است، به این معنا که نیازی به اعلان نوع متغیرها ندارید. + +(بحث {doc}`قبلی ما ` درباره نوع‌های پویا در مقابل ایستا را ببینید.) + +با این حال، Python از **راهنمای نوع** اختیاری (که به عنوان حاشیه‌نویسی نوع نیز شناخته می‌شود) پشتیبانی می‌کند که به شما اجازه می‌دهد نوع‌های مورد انتظار متغیرها، پارامترهای تابع و مقادیر بازگشتی را مشخص کنید. + +راهنمای نوع از Python 3.5 معرفی شد و در نسخه‌های بعدی تکامل یافت. +تمام نحو نشان داده شده در اینجا در Python 3.9 و نسخه‌های بعدی کار می‌کند. + +```{note} +راهنمای نوع *در زمان اجرا توسط مفسر Python نادیده گرفته می‌شود* --- آن‌ها بر نحوه اجرای کد شما تأثیر نمی‌گذارند. آن‌ها صرفاً اطلاعاتی هستند و به عنوان مستندات برای انسان‌ها و ابزارها عمل می‌کنند. +``` + +### نحو پایه -تفاوت این است که توابع با `*args` قادر خواهند بود *آرگومان‌های موضعی* با اندازه دلخواه بپذیرند، در حالی که `**kargs` به توابع اجازه می‌دهد تعداد دلخواه *آرگومان‌های کلیدواژه‌ای* بپذیرند. +راهنمای نوع از دو نقطه `:` برای حاشیه‌نویسی متغیرها و پارامترها، و از پیکان `->` برای حاشیه‌نویسی نوع‌های بازگشتی استفاده می‌کند. -## Decoratorها و Descriptorها +در اینجا یک مثال ساده آورده شده است: + +```{code-cell} python3 +def greet(name: str, times: int) -> str: + return (name + '! ') * times + +greet('hello', 3) +``` + +در این تعریف تابع: + +- `name: str` نشان می‌دهد که `name` انتظار می‌رود یک رشته باشد +- `times: int` نشان می‌دهد که `times` انتظار می‌رود یک عدد صحیح باشد +- `-> str` نشان می‌دهد که تابع یک رشته برمی‌گرداند + +همچنین می‌توانید متغیرها را مستقیماً حاشیه‌نویسی کنید: + +```{code-cell} python3 +x: int = 10 +y: float = 3.14 +name: str = 'Python' +``` + +### نوع‌های رایج + +پرکاربردترین راهنماهای نوع، نوع‌های داخلی هستند: + +| نوع | مثال | +|-----------|----------------------------------| +| `int` | `x: int = 5` | +| `float` | `x: float = 3.14` | +| `str` | `x: str = 'hello'` | +| `bool` | `x: bool = True` | +| `list` | `x: list = [1, 2, 3]` | +| `dict` | `x: dict = {'a': 1}` | + +برای ظرف‌ها، می‌توانید نوع‌های عناصر آن‌ها را مشخص کنید: + +```{code-cell} python3 +prices: list[float] = [9.99, 4.50, 2.89] +counts: dict[str, int] = {'apples': 3, 'oranges': 5} +``` + +### راهنماها نوع را اعمال نمی‌کنند + +یک نکته مهم برای برنامه‌نویسان جدید Python: راهنمای نوع در زمان اجرا *اعمال نمی‌شود*. + +Python در صورتی که نوع «اشتباه» را ارسال کنید خطایی ایجاد نمی‌کند: + +```{code-cell} python3 +def add(x: int, y: int) -> int: + return x + y + +# Passes floats — Python doesn't complain +add(1.5, 2.7) +``` + +راهنماها `int` می‌گویند، اما Python با خوشحالی آرگومان‌های `float` را می‌پذیرد و `4.2` را برمی‌گرداند --- که آن هم `int` نیست. + +این تفاوت اساسی با زبان‌های با نوع‌دهی ایستا مانند C یا Java است، که در آن‌ها عدم تطابق نوع‌ها باعث خطاهای کامپایل می‌شود. + +### چرا از راهنمای نوع استفاده کنیم؟ + +اگر Python آن‌ها را نادیده می‌گیرد، چرا زحمت بکشیم؟ + +1. **خوانایی**: راهنمای نوع امضای تابع را خودمستندساز می‌کند. خواننده فوراً می‌داند که تابع چه نوع‌هایی را انتظار دارد و چه چیزی برمی‌گرداند. +2. **پشتیبانی ویرایشگر**: محیط‌های توسعه یکپارچه مانند VS Code از راهنمای نوع برای ارائه تکمیل خودکار بهتر، تشخیص خطا و مستندات درخطی استفاده می‌کنند. +3. **بررسی خطا**: ابزارهایی مانند [mypy](https://mypy.readthedocs.io/) و [pyrefly](https://pyrefly.org/) راهنمای نوع را تحلیل می‌کنند تا اشکالات را *قبل از* اجرای کد شما شناسایی کنند. +4. **کد تولیدشده توسط مدل‌های زبانی بزرگ**: مدل‌های زبانی بزرگ اغلب کدی با راهنمای نوع تولید می‌کنند، بنابراین درک نحو به شما کمک می‌کند خروجی آن‌ها را بخوانید و استفاده کنید. + +### راهنمای نوع در Python علمی + +راهنمای نوع به بحث {doc}`نیاز به سرعت ` مرتبط است: + +* کتابخانه‌های پرعملکرد مانند [JAX](https://jax.readthedocs.io/) و [Numba](https://numba.pydata.org/) برای کامپایل کد ماشین سریع به دانستن نوع متغیرها متکی هستند. +* در حالی که این کتابخانه‌ها نوع‌ها را در زمان اجرا استنتاج می‌کنند نه اینکه مستقیماً راهنمای نوع Python را بخوانند، *مفهوم* یکسان است --- اطلاعات صریح نوع، بهینه‌سازی را ممکن می‌سازد. +* با تکامل اکوسیستم Python، انتظار می‌رود ارتباط بین راهنمای نوع و ابزارهای عملکرد رشد کند. + +در حال حاضر، مزیت اصلی راهنمای نوع در Python روزانه *وضوح و پشتیبانی ابزار* است که با رشد اندازه برنامه‌ها ارزش آن به طور فزاینده‌ای افزایش می‌یابد. + +## دکوراتورها و توصیف‌گرها ```{index} single: Python; Decorators ``` @@ -492,26 +612,26 @@ arb(l1=l1, l2=l2, l3=l3) ```{index} single: Python; Descriptors ``` -بیایید به برخی از عناصر نحوی خاص نگاه کنیم که به طور معمول توسط توسعه‌دهندگان Python استفاده می‌شوند. +بیایید برخی از عناصر نحوی خاصی را که به‌طور معمول توسط برنامه‌نویسان پایتون استفاده می‌شود، بررسی کنیم. -ممکن است بلافاصله به مفاهیم زیر نیاز نداشته باشید، اما آن‌ها را در کد دیگران خواهید دید. +ممکن است به مفاهیم زیر بلافاصله نیاز نداشته باشید، اما آن‌ها را در کدهای دیگران خواهید دید. -از این رو در مرحله‌ای از آموزش Python خود باید آن‌ها را درک کنید. +از این رو، در مرحله‌ای از آموزش پایتون خود باید آن‌ها را درک کنید. -### Decoratorها +### دکوراتورها ```{index} single: Python; Decorators ``` -Decoratorها کمی نحو شیرین هستند که، اگرچه به راحتی قابل اجتناب هستند، محبوب شده‌اند. +دکوراتورها نوعی قند نحوی هستند که هرچند به‌راحتی می‌توان از آن‌ها اجتناب کرد، اما محبوبیت زیادی پیدا کرده‌اند. -بسیار آسان است بگوییم که decoratorها چه کاری انجام می‌دهند. +توضیح اینکه دکوراتورها چه می‌کنند بسیار آسان است. -از طرف دیگر توضیح اینکه *چرا* ممکن است از آن‌ها استفاده کنید، کمی تلاش می‌طلبد. +از سوی دیگر، توضیح *چرایی* استفاده از آن‌ها کمی تلاش می‌طلبد. #### یک مثال -فرض کنید روی برنامه‌ای کار می‌کنیم که شبیه این است +فرض کنید روی برنامه‌ای کار می‌کنیم که چیزی شبیه به این است ```{code-cell} python3 import numpy as np @@ -525,17 +645,17 @@ def g(x): # Program continues with various calculations using f and g ``` -اکنون فرض کنید مشکلی وجود دارد: گاهی اوقات اعداد منفی به `f` و `g` در محاسباتی که دنبال می‌شود، وارد می‌شوند. +حال فرض کنید مشکلی وجود دارد: گاهی اوقات اعداد منفی در محاسباتی که پس از این می‌آیند به `f` و `g` داده می‌شوند. -اگر امتحان کنید، خواهید دید که وقتی این توابع با اعداد منفی فراخوانی می‌شوند، یک شیء NumPy به نام `nan` را برمی‌گردانند. +اگر امتحان کنید، خواهید دید که وقتی این توابع با اعداد منفی فراخوانی می‌شوند، یک شیء NumPy به نام `nan` برمی‌گردانند. -این مخفف "not a number" است (و نشان می‌دهد که شما در حال ارزیابی یک تابع ریاضی در نقطه‌ای هستید که تعریف نشده است). +این مخفف "not a number" (عدد نیست) است (و نشان می‌دهد که سعی دارید یک تابع ریاضی را در نقطه‌ای که تعریف نشده ارزیابی کنید). -شاید این همان چیزی نیست که می‌خواهیم، زیرا مشکلات دیگری را ایجاد می‌کند که بعداً سخت قابل تشخیص هستند. +شاید این همان چیزی نباشد که می‌خواهیم، زیرا مشکلات دیگری ایجاد می‌کند که بعداً شناسایی آن‌ها دشوار است. -فرض کنید به جای آن می‌خواهیم برنامه هر زمان که این اتفاق می‌افتد خاتمه یابد، با یک پیام خطای معقول. +فرض کنید به جای آن می‌خواهیم برنامه هر بار که این اتفاق می‌افتد با یک پیغام خطای معنادار پایان یابد. -این تغییر به اندازه کافی آسان برای پیاده‌سازی است +پیاده‌سازی این تغییر به اندازه کافی آسان است ```{code-cell} python3 import numpy as np @@ -551,17 +671,17 @@ def g(x): # Program continues with various calculations using f and g ``` -با این حال متوجه شوید که اینجا کمی تکرار وجود دارد، به شکل دو خط یکسان کد. +اما توجه کنید که در اینجا تکراری وجود دارد، به شکل دو خط کد یکسان. -تکرار کد ما را طولانی‌تر و سخت‌تر برای نگهداری می‌کند، و از این رو چیزی است که سخت تلاش می‌کنیم از آن اجتناب کنیم. +تکرار کد ما را طولانی‌تر و نگهداری آن را سخت‌تر می‌کند، و از این رو چیزی است که سعی می‌کنیم از آن اجتناب کنیم. -اینجا مشکل بزرگی نیست، اما حالا تصور کنید به جای فقط `f` و `g`، ما 20 تابع داریم که باید دقیقاً به همین شکل تغییر کنیم. +در اینجا این موضوع مشکل بزرگی نیست، اما حالا تصور کنید که به جای فقط `f` و `g`، ۲۰ تابع داریم که باید به روش کاملاً یکسانی تغییر دهیم. -این یعنی باید منطق تست (یعنی خط `assert` که غیرمنفی بودن را تست می‌کند) را 20 بار تکرار کنیم. +این بدان معناست که باید منطق آزمون (یعنی خط `assert` که غیرمنفی بودن را بررسی می‌کند) را ۲۰ بار تکرار کنیم. -وضعیت حتی بدتر است اگر منطق تست طولانی‌تر و پیچیده‌تر باشد. +وضعیت اگر منطق آزمون طولانی‌تر و پیچیده‌تر باشد بدتر هم می‌شود. -در این نوع سناریو رویکرد زیر منظم‌تر خواهد بود +در این نوع سناریو، رویکرد زیر منظم‌تر خواهد بود ```{code-cell} python3 import numpy as np @@ -583,41 +703,39 @@ g = check_nonneg(g) # Program continues with various calculations using f and g ``` -این پیچیده به نظر می‌رسد، پس بیایید آرام آرام روی آن کار کنیم. +این پیچیده به نظر می‌رسد پس بیایید آن را به آرامی بررسی کنیم. -برای باز کردن منطق، در نظر بگیرید چه اتفاقی می‌افتد وقتی می‌گوییم `f = check_nonneg(f)`. +برای درک منطق، در نظر بگیرید چه اتفاقی می‌افتد وقتی می‌نویسیم `f = check_nonneg(f)`. -این تابع `check_nonneg` را با پارامتر `func` برابر با `f` فراخوانی می‌کند. +این تابع `check_nonneg` را با پارامتر `func` که برابر `f` تنظیم شده فراخوانی می‌کند. -اکنون `check_nonneg` یک تابع جدید به نام `safe_function` ایجاد می‌کند که -`x` را به عنوان غیرمنفی تأیید می‌کند و سپس `func` را روی آن فراخوانی می‌کند (که همان `f` است). +حالا `check_nonneg` یک تابع جدید به نام `safe_function` می‌سازد که `x` را به عنوان غیرمنفی تأیید می‌کند و سپس `func` را روی آن فراخوانی می‌کند (که همان `f` است). -در نهایت، نام سراسری `f` برابر با `safe_function` قرار می‌گیرد. +در نهایت، نام سراسری `f` برابر `safe_function` تنظیم می‌شود. -اکنون رفتار `f` همان‌طور که می‌خواهیم است، و همینطور برای `g`. +حالا رفتار `f` همان‌طور که می‌خواهیم است، و همین موضوع برای `g` نیز صادق است. -در عین حال، منطق تست فقط یک بار نوشته شده است. +در عین حال، منطق آزمون فقط یک‌بار نوشته شده است. -#### Decoratorها وارد می‌شوند +#### ورود دکوراتورها ```{index} single: Python; Decorators ``` -نسخه آخر کد ما هنوز ایده‌آل نیست. +آخرین نسخه کد ما هنوز ایده‌آل نیست. -به عنوان مثال، اگر کسی کد ما را بخواند و بخواهد بداند که -`f` چگونه کار می‌کند، به دنبال تعریف تابع خواهد گشت، که این است +برای مثال، اگر کسی کد ما را می‌خواند و می‌خواهد بداند `f` چگونه کار می‌کند، به دنبال تعریف تابع می‌گردد، که این است ```{code-cell} python3 def f(x): return np.log(np.log(x)) ``` -ممکن است خط `f = check_nonneg(f)` را از دست بدهند. +ممکن است خط `f = check_nonneg(f)` را نادیده بگیرد. -به این و دلایل دیگر، decoratorها به Python معرفی شدند. +به همین دلایل و دلایل دیگر، دکوراتورها به پایتون اضافه شدند. -با decoratorها، می‌توانیم خطوط +با دکوراتورها، می‌توانیم خطوط زیر را ```{code-cell} python3 def f(x): @@ -630,7 +748,7 @@ f = check_nonneg(f) g = check_nonneg(g) ``` -را با +با این جایگزین کنیم ```{code-cell} python3 @check_nonneg @@ -642,33 +760,30 @@ def g(x): return np.sqrt(42 * x) ``` -جایگزین کنیم - این دو قطعه کد دقیقاً همان کار را انجام می‌دهند. -اگر همان کار را انجام می‌دهند، آیا واقعاً به نحو decorator نیاز داریم؟ +اگر همان کار را انجام می‌دهند، آیا واقعاً به نحو دکوراتور نیاز داریم؟ -خب، توجه کنید که decoratorها دقیقاً بالای تعاریف تابع قرار دارند. +خب، توجه کنید که دکوراتورها درست بالای تعاریف تابع قرار دارند. -بنابراین هر کسی که به تعریف تابع نگاه می‌کند، آن‌ها را خواهد دید و از -اینکه تابع تغییر یافته است، آگاه خواهد شد. +از این رو هر کسی که به تعریف تابع نگاه می‌کند آن‌ها را می‌بیند و از اینکه تابع تغییر یافته آگاه می‌شود. -به نظر بسیاری از افراد، این نحو decorator را به یک بهبود قابل توجه برای زبان تبدیل می‌کند. +به عقیده بسیاری از افراد، این نحو دکوراتور بهبود قابل توجهی برای زبان است. (descriptors)= -### Descriptorها + +### توصیف‌گرها ```{index} single: Python; Descriptors ``` -Descriptorها مشکل رایجی را در مورد مدیریت متغیرها حل می‌کنند. +توصیف‌گرها یک مشکل رایج در مدیریت متغیرها را حل می‌کنند. -برای درک موضوع، یک کلاس `Car` را در نظر بگیرید که یک ماشین را شبیه‌سازی می‌کند. +برای درک مسئله، یک کلاس `Car` را در نظر بگیرید که یک خودرو را شبیه‌سازی می‌کند. -فرض کنید این کلاس متغیرهای `miles` و `kms` را تعریف می‌کند که به ترتیب فاصله طی شده به مایل -و کیلومتر را نشان می‌دهند. +فرض کنید این کلاس متغیرهای `miles` و `kms` را تعریف می‌کند که به ترتیب مسافت طی شده را به مایل و کیلومتر نشان می‌دهند. -یک نسخه بسیار ساده‌شده از کلاس ممکن است به شکل زیر باشد +یک نسخه بسیار ساده‌شده از این کلاس ممکن است به شکل زیر باشد ```{code-cell} python3 class Car: @@ -680,8 +795,7 @@ class Car: # Some other functionality, details omitted ``` -یک مشکل احتمالی که ممکن است اینجا داشته باشیم این است که کاربر یکی از این -متغیرها را تغییر دهد اما دیگری را نه +یک مشکل بالقوه‌ای که ممکن است داشته باشیم این است که کاربر یکی از این متغیرها را تغییر دهد اما نه دیگری را ```{code-cell} python3 car = Car() @@ -697,17 +811,17 @@ car.miles = 6000 car.kms ``` -در دو خط آخر می‌بینیم که `miles` و `kms` همگام نیستند. +در دو خط آخر می‌بینیم که `miles` و `kms` هماهنگ نیستند. -آنچه واقعاً می‌خواهیم یک مکانیسم است که به موجب آن هر زمان که کاربر یکی از این متغیرها را تنظیم می‌کند، *دیگری به طور خودکار به‌روز شود*. +آنچه واقعاً می‌خواهیم مکانیزمی است که هر بار کاربر یکی از این متغیرها را تنظیم می‌کند، *دیگری به‌طور خودکار به‌روزرسانی شود*. #### یک راه‌حل -در Python، این موضوع با استفاده از *descriptorها* حل می‌شود. +در پایتون، این مسئله با استفاده از *توصیف‌گرها* حل می‌شود. -یک descriptor فقط یک شیء Python است که متدهای خاصی را پیاده‌سازی می‌کند. +یک توصیف‌گر فقط یک شیء پایتون است که متدهای خاصی را پیاده‌سازی می‌کند. -این متدها زمانی فعال می‌شوند که شیء از طریق نشانه‌گذاری ویژگی نقطه‌دار قابل دسترسی باشد. +این متدها زمانی فعال می‌شوند که از طریق نمادگذاری دات به شیء دسترسی پیدا کنید. بهترین راه برای درک این موضوع دیدن آن در عمل است. @@ -738,7 +852,7 @@ class Car: kms = property(get_kms, set_kms) ``` -ابتدا بیایید بررسی کنیم که رفتار مورد نظر را دریافت می‌کنیم +ابتدا بیایید بررسی کنیم که رفتار مطلوب را به دست می‌آوریم ```{code-cell} python3 car = Car() @@ -750,27 +864,25 @@ car.miles = 6000 car.kms ``` -بله، این همان چیزی است که می‌خواهیم --- `car.kms` به طور خودکار به‌روز می‌شود. +بله، این همان چیزی است که می‌خواهیم --- `car.kms` به‌طور خودکار به‌روزرسانی می‌شود. -#### چگونه کار می‌کند +#### چگونگی کارکرد آن نام‌های `_miles` و `_kms` نام‌های دلخواهی هستند که برای ذخیره مقادیر متغیرها استفاده می‌کنیم. -اشیاء `miles` و `kms` *propertyها* هستند، نوع رایجی از descriptor. +اشیاء `miles` و `kms` *ویژگی‌ها* (properties) هستند، که نوع رایجی از توصیف‌گر به شمار می‌روند. -متدهای `get_miles`، `set_miles`، `get_kms` و `set_kms` تعریف -می‌کنند که چه اتفاقی می‌افتد وقتی این متغیرها را دریافت (یعنی دسترسی) یا تنظیم (اتصال) می‌کنید +متدهای `get_miles`، `set_miles`، `get_kms` و `set_kms` تعریف می‌کنند که وقتی این متغیرها را دریافت می‌کنید (یعنی دسترسی پیدا می‌کنید) یا تنظیم می‌کنید (مقیدسازی) چه اتفاقی می‌افتد -* متدهای به اصطلاح "getter" و "setter". +* به اصطلاح متدهای "getter" و "setter". -تابع داخلی Python به نام `property` متدهای getter و setter را می‌گیرد و یک property ایجاد می‌کند. +تابع توکار پایتون `property` متدهای getter و setter را می‌گیرد و یک ویژگی می‌سازد. -به عنوان مثال، بعد از اینکه `car` به عنوان یک نمونه از `Car` ایجاد شد، شیء `car.miles` یک property است. +برای مثال، پس از اینکه `car` به عنوان یک نمونه از `Car` ساخته می‌شود، شیء `car.miles` یک ویژگی است. -به عنوان یک property، وقتی مقدار آن را از طریق `car.miles = 6000` تنظیم می‌کنیم، متد setter -آن فعال می‌شود --- در این مورد `set_miles`. +از آنجا که یک ویژگی است، وقتی مقدار آن را از طریق `car.miles = 6000` تنظیم می‌کنیم، متد setter آن فعال می‌شود --- در این حالت `set_miles`. -#### Decoratorها و Propertyها +#### دکوراتورها و ویژگی‌ها ```{index} single: Python; Decorators ``` @@ -778,10 +890,9 @@ car.kms ```{index} single: Python; Properties ``` -این روزها بسیار رایج است که تابع `property` را از طریق یک decorator ببینید. +این روزها بسیار رایج است که تابع `property` از طریق یک دکوراتور استفاده شود. -اینجا نسخه دیگری از کلاس `Car` ما است که مانند قبل کار می‌کند اما حالا از -decoratorها برای تنظیم propertyها استفاده می‌کند +این نسخه دیگری از کلاس `Car` ما است که مثل قبل کار می‌کند اما حالا از دکوراتورها برای تنظیم ویژگی‌ها استفاده می‌کند ```{code-cell} python3 class Car: @@ -809,11 +920,12 @@ class Car: self._miles = value / 1.61 ``` -از همه جزئیات اینجا نمی‌گذریم. +در اینجا تمام جزئیات را بررسی نخواهیم کرد. -برای اطلاعات بیشتر می‌توانید به [مستندات descriptor](https://docs.python.org/3/howto/descriptor.html) مراجعه کنید. +برای اطلاعات بیشتر می‌توانید به [مستندات توصیف‌گر](https://docs.python.org/3/howto/descriptor.html) مراجعه کنید. (paf_generators)= + ## Generatorها ```{index} single: Python; Generators @@ -1084,7 +1196,6 @@ sum(draws) * نیاز به ایجاد لیست‌ها/tupleهای بزرگ را از بین می‌برند، و * یک رابط یکنواخت برای تکرار فراهم می‌کنند که می‌تواند به صورت شفاف در حلقه‌های `for` استفاده شود - ## تمرین‌ها @@ -1092,7 +1203,7 @@ sum(draws) :label: paf_ex1 ``` -کد زیر را کامل کنید و آن را با استفاده از [این فایل csv](https://raw.githubusercontent.com/QuantEcon/lecture-python-programming/master/source/_static/lecture_specific/python_advanced_features/test_table.csv) تست کنید، که فرض می‌کنیم آن را در دایرکتوری کاری فعلی خود قرار داده‌اید +کد زیر را کامل کنید و آن را با استفاده از [این فایل csv](https://raw.githubusercontent.com/QuantEcon/lecture-python-programming/main/lectures/_static/lecture_specific/python_advanced_features/test_table.csv) تست کنید، که فرض می‌کنیم آن را در دایرکتوری کاری فعلی خود قرار داده‌اید ```{code-block} python3 :class: no-execute @@ -1145,4 +1256,4 @@ for date in dates: ``` ```{solution-end} -``` \ No newline at end of file +``` From 7e8c45451fac6b75197ea7652d6daa1d2e317bfe Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 23 Mar 2026 05:15:08 +0000 Subject: [PATCH 4/4] Update translation: .translate/state/python_advanced_features.md.yml --- .translate/state/python_advanced_features.md.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.translate/state/python_advanced_features.md.yml b/.translate/state/python_advanced_features.md.yml index 565ebad..a1afd0a 100644 --- a/.translate/state/python_advanced_features.md.yml +++ b/.translate/state/python_advanced_features.md.yml @@ -1,6 +1,6 @@ -source-sha: 1a87942398e15e03539083cc944a78653c532607 -synced-at: "2026-03-20" -model: unknown -mode: RESYNC -section-count: 6 -tool-version: 0.11.0 +source-sha: 02e57a5befc2a9a081019edc748aba15e4b2f02a +synced-at: "2026-03-23" +model: claude-sonnet-4-6 +mode: UPDATE +section-count: 7 +tool-version: 0.11.2