Skip to content

Commit 980ac37

Browse files
author
Saeid Darvish
authored
Merge pull request #38 from saeiddrv/draft
UPDATE#00125
2 parents 4319d03 + d91a4bc commit 980ac37

11 files changed

Lines changed: 880 additions & 9 deletions
28.8 KB
Loading
33.3 KB
Loading

_static/sitemap-index.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@
129129
<lastmod>2021-03-29T17:10:25+00:00</lastmod>
130130
<priority>0.80</priority>
131131
</url>
132+
<url>
133+
<loc>https://python.coderz.ir/lessons/l24.html</loc>
134+
<lastmod>2021-04-01T17:10:25+00:00</lastmod>
135+
<priority>0.80</priority>
136+
</url>
132137
<url>
133138
<loc>https://python.coderz.ir/log.html</loc>
134139
<lastmod>2021-03-17T17:10:19+00:00</lastmod>

donate-report.rst

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
گزارش حمایت‌های مالی
1010
=========================
1111

12-
مبالغ مهم نیستند، از اقدام و پیام تشویق شما دوستان بسیار سپاسگذارم. (*اطلاعات این صفحه به صورت آنی بروز نمی‌شود!*)
12+
**مبالغ مهم نیستند، از اقدام و پیام تشویق شما دوستان بسیار سپاسگذارم.**
1313

14-
**از ابتدا (1394): 2,121,222 تومان** [آخرین بروزرسانی:‌ 27-12-1399]
14+
(*اطلاعات این صفحه به صورت آنی بروز نمی‌شود!*)
15+
16+
**از ابتدا (1394): 2,201,222 تومان** [آخرین بروزرسانی:‌ 13-01-1400]
1517

1618
----
1719

@@ -25,6 +27,31 @@
2527

2628

2729

30+
31+
32+
33+
34+
35+
36+
.. raw:: html
37+
38+
<p id="7904c5" >54: <strong style="color:#5C6BC0">50,000 تومان</strong> در زمان 20:34 12-01-1400<br><q>از زحمات شما ممنونم . خیلی ناقابل هست</q></p>
39+
40+
----
41+
42+
.. raw:: html
43+
44+
<p id="8d97db" >53: <strong style="color:#5C6BC0">10,000 تومان</strong> در زمان 11:44 12-01-1400<br><q>با تشکر از مطالب خیلی مفید بعضی نکات که به دنبالشون بودم را توی این کتاب پیدا کردم</q></p>
45+
46+
----
47+
48+
.. raw:: html
49+
50+
<p id="779f30" >52: <strong style="color:#5C6BC0">20,000 تومان</strong> در زمان 21:12 11-01-1400<br><q>خیلی هم خوب</q></p>
51+
52+
----
53+
54+
2855
|
2956
3057
**سال 1399: 652,222 تومان**

index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
lessons/l21
5050
lessons/l22
5151
lessons/l23
52+
lessons/l24
5253
log
5354
donate-report
5455
python-interactive

lessons/l11.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
:keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, انواع شی, انواع داده, پایتون
66

77

8-
درس ۱۱: کتابخانه استاندارد پایتون: math و os
9-
================================================
8+
درس ۱۱: ماژول‌های math (تابع‌های ریاضی) و os (ارتباط با سیستم‌عامل) پایتون
9+
============================================================================
1010

1111
.. figure:: /_static/pages/11-python-os-path-math.jpg
1212
:align: center

lessons/l16.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
:keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, تابع, کتابخانه, پایتون, re
66

77

8-
درس ۱۶: کتابخانه استاندارد پایتون: re
8+
درس ۱۶: ماژول re (عبارات باقاعده) پایتون
99
============================================================================
1010

1111
.. figure:: /_static/pages/16-python-regex-re.jpg

lessons/l21.rst

Lines changed: 165 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
.. role:: emoji-size
22

33
.. meta::
4-
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، OOP در پایتون، Decorators در پایتون، Descriptors در پایتون، property@ در پایتون
4+
:description: کتاب آموزش زبان برنامه نویسی پایتون به فارسی، آموزش شی گرایی در پایتون، OOP در پایتون، Decorators در پایتون، Descriptors در پایتون، property@ در پایتون، Context Manager در پایتون، دستور with / as
55
:keywords: آموزش, آموزش پایتون, آموزش برنامه نویسی, پایتون, Decorators, کتابخانه, پایتون, شی گرایی در پایتون, Descriptors,property@
66

77

8-
درس ۲۱: شی گرایی (OOP) در پایتون: __Descriptors ،Decorator ،__slots و property@
8+
درس ۲۱: شی گرایی (OOP) در پایتون: Context Manager ،Descriptors ،Decorator
99
===================================================================================================
1010

1111
.. figure:: /_static/pages/21-python-object-oriented-programming-property-descriptors.jpg
1212
:align: center
13-
:alt: شی گرایی (OOP) در پایتون: __Descriptors ،Decorator ،__slots و property@
13+
:alt: شی گرایی (OOP) در پایتون: __Descriptors ، Context Manager ،Decorator ،__slots و property@
1414

1515
Photo by `Mathyas Kurmann <https://unsplash.com/photos/fb7yNPbT0l8>`__
1616

@@ -745,6 +745,168 @@ property@
745745
.. tip::
746746

747747
از ``property@`` تنها برای Instance Attributeها می‌توان استفاده کرد.
748+
749+
750+
Context Manager و دستور ``with/as``
751+
------------------------------------------
752+
753+
یکی دیگر از قابلیت‌های کمتر شناخته شده در زبان برنامه‌نویسی پایتون، Context Manager می‌باشد [`اسناد پایتون <http://docs.python.org/3/library/stdtypes.html#typecontextmanager>`__]. با این حال اکثر برنامه‌نویسان پایتون به صورت مداوم از آن بهره می‌گیرند. اگر درس دهم را به یاد داشته باشیم، از دستور ``with/as`` برای کار با فایل‌ها در پایتون استفاده می‌کردیم و شاهد راحتی و زیبایی کارها نسبت به قبل بودیم. در آن زمان تنها اشاره شد که شی فایل پایتون را می‌توان با دستور ``with/as`` استفاده کرد چون این شی از قابلیت Context Manager پشتیبانی می‌کند.
754+
755+
به صورت کلی Context Manager در زبان برنامه‌نویسی پایتون قابلیتی برای مدیرت منابع (فایل‌ها، دیتابیس، ارتباط و سایر منابع) می‌باشد، منابعی که کار کردن با آن‌ها همواره نیازمند عملیات‌ ثابتی همچون باز (Open) و بسته (Close) - Start/Stop, Lock/Release, Change/Reset - کردن هستند.
756+
757+
در این بخش می‌خواهیم به بررسی چگونگی ایجاد یک کلاس به همراه قابلیت Context Manager بپردازیم که در نهایت از اشیای آن بتوانیم در کنار دستور ``with/as`` استفاده نماییم. ابتدا اجازه دهید بار دیگر ساختار دستور ``with/as`` را بررسی نماییم::
758+
759+
with context_expression [as target]:
760+
with_statement_body
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__>`__] را در کلاس مورد نظر خود پیاده‌سازی کنیم:
763+
764+
.. code-block:: python
765+
:linenos:
766+
767+
class SampleContextManager:
768+
def __enter__(self):
769+
print('---> Entered into context manager!')
770+
771+
def __exit__(self, *args):
772+
print('<--- Exiting from context manager!')
773+
774+
775+
with SampleContextManager():
776+
print('Inside context manager!')
777+
778+
::
779+
780+
---> Entered into context manager!
781+
Inside context manager!
782+
<--- Exiting from context manager!
783+
784+
همانطوری که از خروجی نمونه کد بالا قابل مشاهده می‌باشد، در هنگام اجرای دستور ``with``، ابتدا متد ``__enter__`` از شی Context Manager و سپس دستورات داخل بدنه دستور ``with`` و در نهایت نیز متد ``__exit__`` از شی Context Manager اجرا می‌گردد.
785+
786+
787+
اگر بخواهیم کمی عمیق‌تر به ماجرا نگاه کنیم:
788+
789+
* اجرای متد ``__enter__`` زمانی است که خط اجرای برنامه می‌خواهد وارد اجرای دستورات داخل ``with`` یا به اصطلاح وارد runtime context شود و خروجی این متد می‌بایست شی‌ای باشد که می‌خواهیم در طول اجرای دستور ``with`` یا به اصطلاح context، با آن کار کنیم. البته خروجی می‌تواند ``None`` باشد ولی باید توجه داشت که خروجی این متد است که توسط دستور ``as`` به نام ``target`` ارجاع می‌خورد!
790+
791+
* اجرای متد ``__exit__`` زمانی است که انجام کار دستورات ``with`` یا اجرای context به پایان رسیده است. این متد در واقع فرصتی برای تمیزکاری یا به اصطلاح clean up کردن آثار اجرای context می‌باشد. به مانند پاک کردن فایل‌هایی که موقت ایجاد شده‌اند، حذف اشیای اضافی باقی‌مانده یا انجام عمل بستن یک فایل یا پایان دادن یک ارتباط (Connection) یا...
792+
793+
برای آشنایی بیشتر در نمونه کد زیر یک Wrapper برای شی فایل ایجاد کرده‌ایم:
794+
795+
.. code-block:: python
796+
:linenos:
797+
798+
class FileWritterWrapper:
799+
def __init__(self, filename):
800+
self.filename = filename
801+
802+
def __enter__(self):
803+
self.opened_file = open(self.filename, 'a')
804+
self.opened_file.write('====== OPEN FILE ======\n')
805+
return self.opened_file
806+
807+
def __exit__(self, *args):
808+
self.opened_file.write('\n====== CLOSE FILE ======\n')
809+
self.opened_file.close()
810+
811+
812+
with FileWritterWrapper('test_log.txt') as managed_file:
813+
managed_file.write('Inside context manager!')
814+
815+
محتویات فایل test_log.txt، پس از اجرای کد بالا:
816+
817+
::
818+
819+
820+
====== OPEN FILE ======
821+
Inside context manager!
822+
====== CLOSE FILE ======
823+
824+
به متد ``__exit__`` برگردیم، براساس مستندات پایتون تعریف کامل این متد به شکل زیر است::
825+
826+
__exit__(self, exc_type, exc_value, traceback)
827+
828+
سه پارامتر انتهایی در صورت بروز Exception هنگام اجرای context (دستورات داخل بدنه ``with``) دارای مقدار غیر ``None`` و در غیر این صورت برابر با مقدار ``None`` خواهند بود. وجود این مقادیر به معنی عدم پایان صحیح context می‌باشد که ممکن است بتواند در گرفتن تصمیم شما در زمان خروج از context تاثیر داشته باشد.
829+
830+
.. code-block:: python
831+
:linenos:
832+
833+
class SampleContextManager:
834+
def __enter__(self):
835+
print('---> Entered into context manager!')
836+
837+
def __exit__(self, exc_type, exc_value, traceback):
838+
print('exc_type:', exc_type)
839+
print('exc_value:', exc_value)
840+
print('traceback:', traceback)
841+
print('<--- Exiting from context manager!')
842+
843+
844+
with SampleContextManager():
845+
print('|||||||||Inside context manager! - Top')
846+
a = 8 / 0
847+
print('|||||||||Inside context manager! - Bottom')
848+
849+
850+
print('***FINISH***')
851+
852+
::
853+
854+
---> Entered into context manager!
855+
|||||||||Inside context manager! - Top
856+
exc_type: <class 'ZeroDivisionError'>
857+
exc_value: division by zero
858+
traceback: <traceback object at 0x7f1c8aebd0c8>
859+
<--- Exiting from context manager!
860+
Traceback (most recent call last):
861+
File "sample.py", line 14, in <module>
862+
a = 8 / 0
863+
ZeroDivisionError: division by zero
864+
865+
866+
همان‌طور که از نمونه کد بالا قابل مشاهده است، در زمان اجرای دستورات context یک خطای (تقسیم بر صفر) ``ZeroDivisionError`` رخ داده است. نکته قابل توجه این است که حتی با وجود بروز خطا و ناتمام ماندن اجرای context، ولی بدنه متد ``__exit__`` به صورت کامل اجرا شده است. در واقع مفسر پایتون اعلام Exception را که می‌تواند منجر به توقف کل برنامه شود را به صورت موقت تا پایان اجرا ``__exit__`` معلق نگه می‌دارد.
867+
868+
در چنین حالتی اگر متد ``__exit__`` مقدار ``True`` را برگرداند، مفسر پایتون از بروز Exception خودداری خواهد کرد:
869+
870+
.. code-block:: python
871+
:linenos:
872+
873+
class SampleContextManager:
874+
def __enter__(self):
875+
print('---> Entered into context manager!')
876+
877+
def __exit__(self, exc_type, exc_value, traceback):
878+
print('exc_type:', exc_type)
879+
print('exc_value:', exc_value)
880+
print('traceback:', traceback)
881+
print('<--- Exiting from context manager!')
882+
return True
883+
884+
885+
with SampleContextManager():
886+
print('|||||||||Inside context manager! - Top')
887+
a = 8 / 0
888+
print('|||||||||Inside context manager! - Bottom')
889+
890+
891+
print('***FINISH***')
892+
893+
::
894+
895+
---> Entered into context manager!
896+
|||||||||Inside context manager! - Top
897+
exc_type: <class 'ZeroDivisionError'>
898+
exc_value: division by zero
899+
traceback: <traceback object at 0x7f4b3d520048>
900+
<--- Exiting from context manager!
901+
***FINISH***
902+
903+
یادآوری:‌ می‌دانیم که خروجی هر تابع یا متد به صورت پیش‌فرض برای ``None`` می‌باشد و این مقدار در مقام ارزش‌سنجی بولین، ارزشی برابر با مقدار ``False`` دارد.
904+
905+
*در طی دروس آینده به مبحث Exception و مدیریت آن خواهیم پرداخت.*
906+
907+
908+
909+
748910

749911
|
750912

lessons/l23.rst

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@
677677
******************************
678678
--------> Finished!
679679

680+
680681
روند انتشار Exception
681682
----------------------------
682683

@@ -718,7 +719,6 @@
718719
در نمونه کد بالا همانطور که مشخص است تمام Exceptionها در داخل تابع ``print_sum_div_first`` رخ می‌دهد ولی از آنجا که این تابع فاقد handler می‌باشد، Exceptionها به یک مرحله قبل‌تر یعنی تابع ``action`` تحویل می‌گردند، ولی این تابع تنها یک handler برای ``ZeroDivisionError`` داشته پس تمامی Exceptionهای احتمالی دیگر از جمله ``TypeError`` به یک مرحله قبل‌تر تحویل و خوشبختانه در آن‌جا handle می‌شوند!
719720

720721

721-
722722
مدیریت خطای تودرتو (Nested Exception Handling)
723723
---------------------------------------------------
724724

@@ -727,6 +727,52 @@
727727
البته از آنجا که در یکی از بندهای فلسفه پایتون آمده: `PEP 20: Flat is better than nested <https://www.python.org/dev/peps/pep-0020/>`__ انجام این‌کار چندان پایتونی نمی‌باشد و برنامه‌نویس احتمالا می‌تواند با کمی دقت بیشر از ساختار تودرتو پرهیز کند و کدی به مراتب خواناتر توسعه دهد. به هر حال امکان این کار در زبان برنامه‌نویسی پایتون برای برنامه‌نویس محفوظ نگه‌داشته شده است.
728728

729729

730+
731+
مدیریت خطا و دستور ``with``
732+
--------------------------------------
733+
734+
از درس بیست و یکم با مفهوم Context Manager و ارتباط آن با دستور ``with`` آشنا هستیم. اینکه مدیریت خطا برای این ساختار چگونه باشد به این بستگی دارد که می‌خواهیم در کدام نقطه Exception احتمالی را handle کنیم. بر اساس مفهوم Context Manager، در چند نقطه زیر احتمال بروز Exception وجود دارد:
735+
736+
* داخل متد ``__init__`` کلاس ContextManager
737+
* داخل متد ``__enter__`` کلاس ContextManager
738+
* داخل بدنه دستور ``with``
739+
* داخل متد ``__exit__`` کلاس ContextManager
740+
741+
742+
اگر برایمان مهم نباشد می‌توانیم به صورت زیر یک handler برای بروز Exceptionهای احتمالی در تمام حالات بالا پیاده‌سازی نماییم::
743+
744+
745+
try:
746+
with ContextManager():
747+
do_something()
748+
except Exception as err:
749+
pass
750+
751+
752+
در غیر این صورت می‌توانید مشابه نمونه کد زیر عمل نمایید::
753+
754+
try:
755+
context_manager = ContextManager()
756+
757+
except Exception as err:
758+
# Handler for: '__init__'
759+
760+
else:
761+
try:
762+
with context_manager:
763+
try:
764+
do_something()
765+
766+
except Exception as err:
767+
# Handler for: 'with' body
768+
769+
except Exception as err:
770+
# Handler for: '__enter__' and '__exit__'
771+
772+
773+
[`PEP 343 - Specification: The 'with' Statement <https://www.python.org/dev/peps/pep-0343/#specification-the-with-statement>`__]
774+
775+
730776
کارایی (Performance)
731777
----------------------------
732778

0 commit comments

Comments
 (0)