You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: lessons/l21.rst
+89-3Lines changed: 89 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -759,7 +759,7 @@ Context Manager و دستور ``with/as``
759
759
with context_expression [as target]:
760
760
with_statement_body
761
761
762
-
در این ساختار بخش ``as`` اختیاری بوده و تنها زمانی که در داخل بدنه دستور ``with`` به شی ``context_expression`` نیاز داشته باشیم، استفاده میگردد؛ در این صورت یک ارجاع از شی مورد نیاز به نام دلخواه ``target`` ایجاد و در دسترس قرار میگیرد. ``context_expression`` نیز معرف یک شیای است که توانایی مدیریت یا handle کردن دو وضعیت «ورود به» (entry into) و «خروج از» (exit from) را داشته باشد. برای ایجاد همچین شیای میبایست دو متد خاص ``__enter__`` [`اسناد پایتون <https://docs.python.domainunion.de/3/reference/datamodel.html#object.__enter__>`__] و ``__exit__`` [`اسناد پایتون <https://docs.python.domainunion.de/3/reference/datamodel.html#object.__exit__>`__] را در کلاس مورد نظر خود پیادهسازی کنیم:
762
+
در این ساختار بخش ``as`` اختیاری بوده و تنها زمانی که در داخل بدنه دستور ``with`` به شی تولید شده توسط ``context_expression`` نیاز داشته باشیم، استفاده میگردد؛ در این صورت یک ارجاع از شی مورد نیاز به نام دلخواه ``target`` ایجاد و در دسترس قرار میگیرد. ``context_expression`` نیز معرف یک شیای است که توانایی مدیریت یا handle کردن دو وضعیت «ورود به» (entry into) و «خروج از» (exit from) را داشته باشد. برای ایجاد همچین شیای میبایست دو متد خاص ``__enter__`` [`اسناد پایتون <https://docs.python.domainunion.de/3/reference/datamodel.html#object.__enter__>`__] و ``__exit__`` [`اسناد پایتون <https://docs.python.domainunion.de/3/reference/datamodel.html#object.__exit__>`__] را در کلاس مورد نظر خود پیادهسازی کنیم:
763
763
764
764
.. code-block:: python
765
765
:linenos:
@@ -786,9 +786,9 @@ Context Manager و دستور ``with/as``
786
786
787
787
اگر بخواهیم کمی عمیقتر به ماجرا نگاه کنیم:
788
788
789
-
* اجرای متد ``__enter__`` زمانی است که خط اجرای برنامه به اصطلاح میخواهد وارد runtime context شود و خروجی این متد میبایست شیای باشد که میخواهیم در طول اجرای دستور ``with`` یا به اصطلاح context، با آن کار کنیم. البته خروجی میتواند ``None`` باشد ولی باید توجه داشت که خروجی این متد است که توسط دستور ``as`` به نام ``target`` ارجاع میخورد!
789
+
* اجرای متد ``__enter__`` زمانی است که خط اجرای برنامه میخواهد وارد اجرای دستورات داخل ``with`` یا به اصطلاح وارد runtime context شود و خروجی این متد میبایست شیای باشد که میخواهیم در طول اجرای دستور ``with`` یا به اصطلاح context، با آن کار کنیم. البته خروجی میتواند ``None`` باشد ولی باید توجه داشت که خروجی این متد است که توسط دستور ``as`` به نام ``target`` ارجاع میخورد!
790
790
791
-
* اجرای متد ``__exit__`` زمانی است که کار یا اجرای context به پایان رسیده است. این متد در واقع فرصتی برای تمیزکاری یا به اصطلاح clean up کردن آثار اجرای context میباشد. به مانند پاک کردن فایلهایی که موقت ایجاد شدهاند، حذف اشیای اضافی باقیمانده یا انجام عمل بستن یک فایل یا پایان دادن یک ارتباط (Connection) یا...
791
+
* اجرای متد ``__exit__`` زمانی است که انجام کار دستورات ``with`` یا اجرای context به پایان رسیده است. این متد در واقع فرصتی برای تمیزکاری یا به اصطلاح clean up کردن آثار اجرای context میباشد. به مانند پاک کردن فایلهایی که موقت ایجاد شدهاند، حذف اشیای اضافی باقیمانده یا انجام عمل بستن یک فایل یا پایان دادن یک ارتباط (Connection) یا...
792
792
793
793
برای آشنایی بیشتر در نمونه کد زیر یک Wrapper برای شی فایل ایجاد کردهایم:
794
794
@@ -821,6 +821,92 @@ Context Manager و دستور ``with/as``
821
821
Inside context manager!
822
822
====== CLOSE FILE ======
823
823
824
+
به متد ``__exit__`` برگردیم، براساس مستندات پایتون تعریف کامل این متد به شکل زیر است::
825
+
826
+
__exit__(self, exc_type, exc_value, traceback)
827
+
828
+
سه پارامتر انتهایی در صورت بروز Exception هنگام اجرای context (دستورات داخل بدنه ``with``) دارای مقدار غیر ``None`` و در غیر این صورت برابر با مقدار ``None`` خواهند بود. وجود این مقادیر به معنی عدم پایان صحیح context میباشد که ممکن است بتواند در گرفتن تصمیم شما در زمان خروج از context تاثیر داشته باشد.
همانطور که از نمونه کد بالا قابل مشاهده است، در زمان اجرای دستورات context یک خطای (تقسیم بر صفر) ``ZeroDivisionError`` رخ داده است. نکته قابل توجه این است که حتی با وجود بروز خطا و ناتمام ماندن اجرای context، ولی بدنه متد ``__exit__`` به صورت کامل اجرا شده است. در واقع مفسر پایتون اعلام Exception را که میتواند منجر به توقف کل برنامه شود را به صورت موقت تا پایان اجرا ``__exit__`` معلق نگه میدارد.
867
+
868
+
در چنین حالتی اگر متد ``__exit__`` مقدار ``True`` را برگرداند، مفسر پایتون از بروز Exception خودداری خواهد کرد:
یادآوری: میدانیم که خروجی هر تابع یا متد به صورت پیشفرض برای ``None`` میباشد و این مقدار در مقام ارزشسنجی بولین، ارزشی برابر با مقدار ``False`` دارد.
904
+
905
+
*در طی دروس آینده به مبحث Exception و مدیریت آن خواهیم پرداخت.*
0 commit comments