Skip to content

Commit fe77f6e

Browse files
author
Saeid Darvish
committed
l18: completed
1 parent 7775dd1 commit fe77f6e

1 file changed

Lines changed: 27 additions & 14 deletions

File tree

lessons/l18.rst

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. role:: emoji-size
22

33
.. meta::
4-
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، معرفی رابطه های وراثت (Inheritance) و انجمن (Association) در پایان، OOP در پایتون
4+
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، معرفی رابطه های وراثت (Inheritance) و انجمن (Association) در پایان، OOP در پایتون، ترکیب در پایتون، Method Resolution Order یا MRO پایتون، Composition و Aggregation در پایتون، وراثت چندگانه در پایتون، Multiple Inheritance پایتون
55
:keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, تابع, کتابخانه, پایتون, شی گرایی در پایتون
66

77

@@ -262,6 +262,15 @@
262262
True
263263
>>> isinstance(sub, SuperClass)
264264
True
265+
>>> isinstance(sub, object)
266+
True
267+
268+
در واقع این نمایش رابطه **IS-A** می‌باشد. توجه داشته باشید که این رابطه از پایین به بالا می‌باشد و برعکس آن صادق نیست. برای نمونه، مثال نخست را بیاد آورید. گنجشک (Sparrow) یک Animal است ولی Animal لزوما گنجشک نیست!
269+
270+
تمام کلاس‌های پایتون به صورت ضمنی از کلاس ``object`` ارث‌بری دارند.
271+
272+
273+
265274

266275

267276
وراثت چندگانه (Multiple Inheritance)
@@ -293,11 +302,13 @@
293302
>>> isinstance(sub, SuperClassB)
294303
True
295304
>>> isinstance(sub, SuperClassC)
305+
True
306+
>>> isinstance(sub, object)
296307
True
297308

298309
نمونه کد بالا نمایش ساختار وراثت چندگانه در پایتون است که در آن کلاس SubClass به ترتیب از سه کلاس SuperClassA و SuperClassB و SuperClassC ارث‌بری دارد.
299310

300-
اکنون مهم‌ترین چالش چگونگی دسترسی به متدهای هر یک از این superclassها می‌باشد. تاکنون برای دسترسی به متدهای superclass از تابع ``super`` استفاده می‌کردیم ولی حالا که صحبت از چندین superclass است، مثلا مقدارهی متد ``__init__`` توسط این تابع چگونه می‌تواند انجام شود؟ چگونه باید به پایتون بگوییم آرگومان‌هایی را که می‌خواهیم دقیقا به متد خاصی از superclass مورد نظر ارسال کند؟ البته نگران نباشید، پایتون مشکلی نخواهد داشت. در ادامه، حالات مختلف حل این مسئله را بررسی خواهیم کرد.
311+
اکنون مهم‌ترین چالش چگونگی دسترسی به متدهای هر یک از این superclassها می‌باشد. تاکنون برای دسترسی به متدهای superclass از تابع ``super`` استفاده می‌کردیم ولی حالا که صحبت از چندین superclass است، مثلا مقدارهی متد ``__init__`` (که در تمام superclassها با همین نام وجود دارد) توسط این تابع چگونه می‌تواند انجام شود؟ چگونه باید به پایتون بگوییم آرگومان‌هایی را که می‌خواهیم دقیقا به متد خاصی از superclass مورد نظر ارسال کند؟ البته نگران نباشید، پایتون مشکلی نخواهد داشت. در ادامه، حالات مختلف حل این مسئله را بررسی خواهیم کرد.
301312

302313
**شیوه یکم:** خیلی ساده، می‌توانیم اصلا از تابع ``super`` استفاده نکنیم و متدهای هر superclass را مستقیم با نام خودش فراخوانی کنیم که البته در این روش لازم است به ازای تمام پارامترهای متد superclass آرگومان متناظر را ارسال نماییم، از جمله برای ``self``:
303314

@@ -406,7 +417,9 @@
406417

407418
متدها در کلاس از قوانین حاکم بر تابع در پایتون پیروی می‌کنند، در نتیجه متدهای متناظر در superclassها باید به گونه‌ای تعریف شده باشند که هر تعداد پارامتر را بپذیرند. برای این منظور در انتهای تعریف پارامترهای این متدها، یک پارامتر ``args*`` قرار داده‌ایم. این پارامتر، تمامی آرگومان‌های اضافی ارسال شده به آن تابع را در خود نگه‌داری می‌کند. در نتیجه برای ادامه روند فراخوانی متدهای نظیر باقی‌مانده، تنها کافی است این مقدار ارسال گردد. (تابع در پایتون - درس دوازدهم)
408419

409-
اگر شیوه ارسال آرگومان‌ها را به صورت **نام=مقدار** تغییر دهیم، ترتیب ارسال آرگومان‌ها از اهمیت می‌افتد و پیاده‌سازی آسان‌تر و کد خواناتر خواهد بود:
420+
421+
422+
اگر شیوه ارسال آرگومان‌ها را به صورت **نام=مقدار** تغییر دهیم، ترتیب ارسال آرگومان‌ها از اهمیت می‌افتد و پیاده‌سازی آسان‌تر و کد خواناتر خواهد بود - با این روش چنانچه متدهای مورد نظر در superclasها پارامتر همنام نداشته باشند، حتی ترتیب MRO نیز دیگر اهمیت نخواهد داشت:
410423

411424
.. code-block:: python
412425
:linenos:
@@ -471,7 +484,7 @@ Method Resolution Order
471484
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
472485

473486

474-
۳) محاسبه حاصل الگوریتم C3 linearization برای یک کلاس که بیش از یک سطح سلسله مراتب وراثت دارد کمی زحمت دارد! در حالت کلی این مقدار برابر است با: «لیستی تک عضوی شامل آن کلاس » ``+`` لیستی با اعضای منحصر به فرد که حاصل ادغام (merge) «نتیجه خطی شدن (linearization) superclassهای آن کلاس» و «لیستی از superclassهای آن کلاس». عمل ادغام در اینجا علاوه بر اینکه تکرارپذیر می‌باشد نکاتی دارد که در ادامه ذکر خواهد شد .
487+
۳) محاسبه حاصل الگوریتم C3 linearization برای یک کلاس که بیش از یک سطح سلسله مراتب وراثت دارد کمی زحمت دارد! در حالت کلی این مقدار برابر است با: «لیستی تک عضوی شامل آن کلاس » ``+`` لیستی با اعضای منحصر به فرد که حاصل ادغام (merge) «نتیجه خطی شدن (linearization) تک تک superclassهای آن کلاس» و «لیستی از superclassهای آن کلاس». عمل ادغام در اینجا علاوه بر اینکه تکرارپذیر می‌باشد نکاتی دارد که در ادامه ذکر خواهد شد .
475488

476489
اکنون برای پی بردن به چگونگی ایجاد حاصل ``__Class.__mro`` و درک عملکرد الگوریتم C3 linearization دو مثال معروف در این زمینه را بررسی خواهیم کرد. نخست ساختار الماس (Diamond):
477490

@@ -514,25 +527,25 @@ Method Resolution Order
514527
= [D, B, C, A]
515528
516529
517-
* سطر ۱: حاصل خطی سازی (linearization) کلاس A یا همان L(A) برابر است با لیستی که تنها شامل همان کلاس A است چرا که کلاس A بدون superclass است.
530+
* **سطر ۱:** حاصل خطی سازی (linearization) کلاس A یا همان L(A) برابر است با لیستی که تنها شامل همان کلاس A است چرا که کلاس A بدون superclass است.
518531

519-
* سطر ۳: حاصل خطی سازی (linearization) کلاس B یا همان L(B) برابر است با «لیستی که تنها شامل همان کلاس B» ``+`` ادغام «حاصل خطی سازی (linearization) تک تک superclassهای کلاس B - در اینجا: L(A)» و لیستی از superclassهای کلاس B - در اینجا: [A]
532+
* **سطر ۳:** حاصل خطی سازی (linearization) کلاس B یا همان L(B) برابر است با «لیستی که تنها شامل همان کلاس B» ``+`` ادغام «حاصل خطی سازی (linearization) تک تک superclassهای کلاس B - در اینجا: L(A)» و لیستی از superclassهای کلاس B - در اینجا: [A]
520533

521-
* سطر۴: حاصل L(A) جایگذاری شده است.
534+
* **سطر ۴:** حاصل L(A) جایگذاری شده است.
522535

523-
* سطر ۵: حاصل ادغام چند لیست که تنها شامل یک کلاس می‌باشند برابر است با آن کلاس: ``[A] + [B] = [B,A]``
536+
* **سطر ۵:** حاصل ادغام چند لیست که تنها شامل یک کلاس می‌باشند برابر است با آن کلاس: ``[A] + [B] = [B,A]``
524537

525-
* سطر ۷: حاصل خطی سازی (linearization) کلاس C همانند کلاس B می‌باشد.
538+
* **سطر ۷:** حاصل خطی سازی (linearization) کلاس C همانند کلاس B می‌باشد.
526539

527-
* سطر ۱۱: حاصل خطی سازی (linearization) کلاس D یا همان L(D) برابر است با «لیستی که تنها شامل همان کلاس D» ``+`` ادغام «حاصل خطی سازی (linearization) تک تک superclassهای کلاس D با حفظ ترتیب از چپ به راست - در اینجا: L(B) , L(C)» و لیستی از superclassهای کلاس D با حفظ ترتیب از چپ به راست - در اینجا: [B,C]
540+
* **سطر ۱۱:** حاصل خطی سازی (linearization) کلاس D یا همان L(D) برابر است با «لیستی که تنها شامل همان کلاس D» ``+`` ادغام «حاصل خطی سازی (linearization) تک تک superclassهای کلاس D با حفظ ترتیب از چپ به راست - در اینجا: L(B) , L(C)» و لیستی از superclassهای کلاس D با حفظ ترتیب از چپ به راست - در اینجا: [B,C]
528541

529-
* سطر ۱۲: حاصل L(B) و L(C) جایگذاری شده است.
542+
* **سطر ۱۲:** حاصل L(B) و L(C) جایگذاری شده است.
530543

531-
* سطر ۱۳: اکنون عملیات ادغام شامل بیش از یک کلاس است، در این شرایط عملیات ادغام و انتخاب یک کلاس مطلوب آنقدر تکرار می‌شود تا دیگر کلاسی باقی نماند. فرآیند انتخاب کلاس مطلوب به این صورت است که از چپ‌ترین کلاس موجود در چپ‌ترین لیست شروع می‌کنیم به انتخاب، این کلاس می‌بایست در باقی لیست‌ها در صورت وجود چپ‌ترین عضو باشد، در غیر این صورت چپ‌ترین کلاس موجود در لیست بعدی انتخاب و بررسی خواهد شد. چنانچه کلاس انتخاب شده شرایط را دارا باشد عمل ادغام برای آن کلاس صورت می‌پذیرد و داخل تمام لیست‌ها در صورت وجود نیز حذف می‌گردد. در اینجا: ابتدا کلاس B انتخاب می‌شود، این کلاس شرایط مطلوب بودن را دارا می‌باشد، در نتیجه عمل ادغام برای آن به انجام می‌رسد.
544+
* **سطر ۱۳:** اکنون عملیات ادغام شامل بیش از یک کلاس است، در این شرایط عملیات ادغام و انتخاب یک کلاس مطلوب آنقدر تکرار می‌شود تا دیگر کلاسی باقی نماند. فرآیند انتخاب کلاس مطلوب به این صورت است که از چپ‌ترین کلاس موجود در چپ‌ترین لیست شروع می‌کنیم به انتخاب، این کلاس می‌بایست در باقی لیست‌ها در صورت وجود چپ‌ترین عضو باشد، در غیر این صورت چپ‌ترین کلاس موجود در لیست بعدی انتخاب و بررسی خواهد شد. چنانچه کلاس انتخاب شده شرایط را دارا باشد عمل ادغام برای آن کلاس صورت می‌پذیرد و داخل تمام لیست‌ها در صورت وجود نیز حذف می‌گردد. در اینجا: ابتدا کلاس B انتخاب می‌شود، این کلاس شرایط مطلوب بودن را دارا می‌باشد، در نتیجه عمل ادغام برای آن به انجام می‌رسد.
532545

533-
* سطر ۱۴: در ادامه عمل ادغام فرآیند خطی سازی برای کلاس D، این بار ابتدا کلاس A انتخاب می‌شود، این کلاس شرایط لازم را ندارد چرا که در جایگاهی از لیست دوم نیز حضور دارد که جایگاه نخست (چپ‌ترین) نیست. کلاس A رها می‌شود و به سراغ لیست دوم می‌رویم، نخستین عضو آن یعنی کلاس C شرایط لازم برای ادغام را دارد، در نتیجه در این مرحله عمل ادغام برای کلاس C به انجام می‌رسد.
546+
* **سطر ۱۴:** در ادامه عمل ادغام فرآیند خطی سازی برای کلاس D، این بار ابتدا کلاس A انتخاب می‌شود، این کلاس شرایط لازم را ندارد چرا که در جایگاهی از لیست دوم نیز حضور دارد که جایگاه نخست (چپ‌ترین) نیست. کلاس A رها می‌شود و به سراغ لیست دوم می‌رویم، نخستین عضو آن یعنی کلاس C شرایط لازم برای ادغام را دارد، در نتیجه در این مرحله عمل ادغام برای کلاس C به انجام می‌رسد.
534547

535-
* سطر ۱۵: حاصل ادغام چند لیست که تنها شامل یک کلاس می‌باشند برابر است با همان کلاس، در نتیجه کلاس A انتخاب و عمل ادغام برای آن به انجام می‌رسد.
548+
* **سطر ۱۵:** حاصل ادغام چند لیست که تنها شامل یک کلاس می‌باشند برابر است با همان کلاس، در نتیجه کلاس A انتخاب و عمل ادغام برای آن به انجام می‌رسد.
536549

537550
عملیات با موفقیت به پایان رسید و ما به مقداری برابر با ``__D.__mro`` دست پیدا کردیم!
538551

0 commit comments

Comments
 (0)