Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit df59bf3

Browse filesBrowse files
author
Saeid Darvish
committed
l24: working on warnings
1 parent e4046f8 commit df59bf3
Copy full SHA for df59bf3

File tree

Expand file treeCollapse file tree

2 files changed

+239
-3
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+239
-3
lines changed
Open diff view settings
Collapse file
33.3 KB
  • Display the source diff
  • Display the rich diff
Loading
Collapse file

‎lessons/l24.rst‎

Copy file name to clipboardExpand all lines: lessons/l24.rst
+239-3Lines changed: 239 additions & 3 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,248 @@
236236
در زبان‌برنامه‌نویسی پایتون پیشنهاد می‌شود که اگر هدف از ایجاد Exception نمایش یک خطا باشد، در انتهای نام کلاس از واژه Error استفاده گردد.
237237

238238

239-
Context Manager و ``with``
239+
ماژول warnings
240240
~~~~~~~~~~~~~~~~~~~~~~~~~~~
241241

242+
تا این لحظه با مفهوم Exception آشنا شده‌ایم. می‌دانیم که بروز Exception در واقع اعلام یک خطا یا یک رویداد مهم در برنامه می‌باشد که می‌بایست حتما handle شود، در غیر این صورت برنامه قادر به انجام دستورات نخواهد بود.
242243

243-
ماژول warnings
244-
~~~~~~~~~~~~~~~~~~~~~~~~~~~
244+
اما گاهی اعلام یک رویداد آنقدر مهم نیست که بخواهد روند اجرای برنامه تهدید کند. بلکه صرفا یک هشدار برای توجه بیشتر یا اصلاح رفتار برای نسخه‌های بعدی خواهد بود که **بیشتر کاربرد آن برای توسعه‌دهندگان برنامه می‌باشد تا کاربرانی که به نوعی مصرف‌کنندگان آن برنامه محسوب می‌شوند**. در زبان برنامه‌نویسی پایتون، ماژول ``warnings`` [`اسناد پایتون <https://docs.python.org/3/library/warnings.html>`__] را برای استفاده در چنین زمان‌هایی فراهم آورده شده است [`PEP 230 <https://www.python.org/dev/peps/pep-0230>`__].
245+
246+
247+
پیش از مراجعه به این ماژول از کتابخانه استاندارد زبان برنامه‌نویسی پایتون لازم است نگاهی دوباره به انتهای فهرست سلسله‌مراتب وراثت Exceptionها که در درس پیش آن را بررسی کردیم بیاندازیم، در انتهای این فهرست کلاس‌هایی با پسوند Warning قراردارند [`Exception hierarchy <https://docs.python.org/3/library/exceptions.html#exception-hierarchy>`__]:
248+
249+
250+
.. image:: /_static/l24-python-exception-hierarchy-warnings.png
251+
:align: center
252+
:alt: Exception Hierarchy در پایتون به همراه warnings
253+
254+
همان‌طور که مشاهده می‌شود، تمام این کلاس‌ها از کلاسی با نام ``Warning`` ارث‌بری دارند که خود این کلاس نیز از کلاس ``Exception`` ارث‌بری دارد.
255+
256+
این‌ها Warning هستند، Exceptionهایی که هدف از توسعه آنها اعلام یک هشدار می‌باشد و نه اعتراضی که تنبیه آن توقف برنامه باشد. با این حال به نمونه کد زیر توجه نمایید:
257+
258+
.. code-block:: python
259+
:linenos:
260+
261+
def sum_int(a, b):
262+
raise DeprecationWarning('"sum_int" will be removed in version 2.0')
263+
sum = a + b
264+
print(sum)
265+
266+
267+
sum_int(6, 5)
268+
print('Done.')
269+
270+
::
271+
272+
Traceback (most recent call last):
273+
File "sample.py", line 7, in <module>
274+
sum_int(6, 5)
275+
File "sample.py", line 2, in sum_int
276+
raise DeprecationWarning('"sum_int" will be removed in version 2.0')
277+
DeprecationWarning: "sum_int" will be removed in version 2.0
278+
279+
ساختار سلسله‌مراتب به ما گفته بود که Warningها در اصل Exception هستند و زمانی که یک Exception به اصطلاح raise شود، حتما می‌بایست یک handler برای آن پیش‌بینی شده باشد. در واقع اگر برای بروز یک Warning از دستور ``raise`` استفاده شود، دستور ``raise`` همان کاری را با Warning انجام می‌دهد که با هر نوع Exception دیگری انجام خواهد داد.
280+
281+
282+
تابع ``warnings.warn``
283+
---------------------------
284+
285+
286+
اگر بخواهیم بروز یک Exception به صورتی هشدارگونه باشد، می‌بایست به سراغ ماژول ``warnings`` برویم. اکنون اگر نمونه کد قبل را با کمک این ماژول بازنویسی نماییم، نتیجه زیر حاصل می‌گردد:
287+
288+
.. code-block:: python
289+
:linenos:
290+
291+
import warnings
292+
293+
def sum_int(a, b):
294+
warnings.warn('"sum_int" will be removed in version 2.0', DeprecationWarning)
295+
sum = a + b
296+
print(sum)
297+
298+
299+
sum_int(6, 5)
300+
print('Done.')
301+
302+
::
303+
304+
sample.py:4: DeprecationWarning: "sum_int" will be removed in version 2.0
305+
warnings.warn('"sum_int" will be removed in version 2.0', DeprecationWarning)
306+
11
307+
Done.
308+
309+
همان‌طور که مشاهده می‌شود تنها یک پیام هشدار در خروجی چاپ (print) می‌شود و دیگر خبری از Traceback نیست و برنامه بدون هیچ اخلالی باموفقیت تا خط پایان به اجرای خود ادامه داده است.
310+
311+
312+
برای اعلام یک هشدار از تابع ``warn`` در ماژول ``warnings`` استفاده می‌شود [`اسناد پایتون <https://docs.python.org/3/library/warnings.html#warnings.warn>`__] که تعریف آن به شکل زیر می‌باشد::
313+
314+
warn(message, category=None, stacklevel=1, source=None)
315+
316+
بر اساس تعریف، این تابع یک پارامتر اجباری (``message``) و سه پارامتر اختیاری دارد.
317+
318+
* **message**: می‌بایست یک شی ``str`` باشد و متن هشداری است که می‌خواهیم نمایش داده شود.
319+
320+
* **category**: نوع Warning را مشخص می‌کند که می‌بایست **نام یک subclass از کلاس** ``Warning`` باشد. برای مشاهده انواع Warningهای از پیش آماده در پایتون می‌توانید به `Warning Categories <https://docs.python.org/3/library/warnings.html#warning-categories>`__ مراجعه نمایید. ارسال آرگومان برای این پارامتر اختیاری است و در صورت عدم ارسال، نوع ``UserWarning`` به صورت پیش‌فرض در نظر گرفته خواهد شد.
321+
322+
* **stacklevel**: اگر دقت کرده باشید متن هشدار شامل اطلاعاتی از محل بروز آن می‌باشد. این پارامتر یک عدد از نوع ``int`` و بزرگتر یا مساوی از ``1`` را دریافت و تعیین می‌کند که این اطلاعات مربوط به کدام سطح از فراخوانی کد و رسیدن به این هشدار باشد. به این صورت که: عدد ``1`` (مقدار پیش‌فرض) به محل دقیق بروز هشدار، عدد ``2`` به یک مرحله قبل‌تر از محل بروز هشدار و ...
323+
324+
.. code-block:: python
325+
:linenos:
326+
327+
328+
import warnings
329+
330+
def sum_int(a, b):
331+
print('-' * 30, 'stacklevel=1')
332+
warnings.warn('"sum_int" will be removed in version 2.0', stacklevel=1)
333+
print('-' * 30, 'stacklevel=2')
334+
warnings.warn('"sum_int" will be removed in version 2.0', stacklevel=2)
335+
print('-' * 30, 'stacklevel=3')
336+
warnings.warn('"sum_int" will be removed in version 2.0', stacklevel=3)
337+
print('-' * 30, 'stacklevel=4')
338+
warnings.warn('"sum_int" will be removed in version 2.0', stacklevel=4)
339+
print('-' * 30, 'stacklevel=5')
340+
warnings.warn('"sum_int" will be removed in version 2.0', stacklevel=5)
341+
print('-' * 30)
342+
sum = a + b
343+
print(sum)
344+
345+
346+
def action(a, b):
347+
sum_int(6, 5)
348+
349+
350+
action(6, 5)
351+
print('Done.')
352+
353+
::
354+
355+
------------------------------ stacklevel=1
356+
sample.py:5: UserWarning: "sum_int" will be removed in version 2.0
357+
warnings.warn('"sum_int" will be removed in version 2.0', stacklevel=1)
358+
------------------------------ stacklevel=2
359+
sample.py:20: UserWarning: "sum_int" will be removed in version 2.0
360+
sum_int(6, 5)
361+
------------------------------ stacklevel=3
362+
sample.py:23: UserWarning: "sum_int" will be removed in version 2.0
363+
action(6, 5)
364+
------------------------------ stacklevel=4
365+
sys:1: UserWarning: "sum_int" will be removed in version 2.0
366+
------------------------------ stacklevel=5
367+
------------------------------
368+
11
369+
Done.
370+
371+
Warnings Filter
372+
----------------------
373+
374+
حالتی را تصور کنید که برنامه شما پر از Warningهای متنوع می‌باشد. Warnings Filter امکانی است برای اینکه مشخص کنیم کدام نوع Warning نادیده گرفته شود یا کدام نوع نمایش داده شود یا کدام نوع همچون یک Exception واقعی رفتار کند. برای این منظور از از تابع ``simplefilter`` در ماژول ``warnings`` استفاده می‌شود [`اسناد پایتون <https://docs.python.org/3/library/warnings.html#warnings.simplefilter>`__] که تعریف آن به شکل زیر می‌باشد::
375+
376+
simplefilter(action, category=Warning, lineno=0, append=False)
377+
378+
بر اساس تعریف، این تابع یک پارامتر اجباری (``action``) و سه پارامتر اختیاری دارد.
379+
380+
381+
* **action**: از نوع ``str`` بوده و می‌تواند یکی از مقادیر پایین باشد. این مشخص می‌کند که چه عملیاتی می‌بایست بر روی Warningها اعمال شود:
382+
383+
.. container:: table
384+
385+
====================== ===================================================================
386+
مقدار توضیحات
387+
====================== ===================================================================
388+
``'default'`` حالت پیش‌فرض، هر Warning به ازای سطری که در آن قرار دارد یکبار چاپ شود
389+
``'error'`` تبدیل رفتار Warning به Exception واقعی - بروز خطا
390+
``'ignore'`` نادیده گرفتن Warning
391+
``'always'`` Warning هر بار چاپ شود
392+
``'module'`` هر Warning به ازای هر ماژول تنها یکبار چاپ شود
393+
``'once'`` هر Warning به ازای کل برنامه تنها یکبار چاپ شود
394+
====================== ===================================================================
395+
396+
* **category**: نوع Warning را مشخص می‌کند که می‌بایست **نام یک subclass از کلاس** ``Warning`` باشد. ارسال آرگومان برای این پارامتر اختیاری است و در صورت عدم ارسال، عمل مشخص شده توسط پارامتر action برای تمام انواع Warningها در برنامه اعمال می‌گردد.
397+
398+
به نمونه کدهای زیر توجه نمایید:
399+
400+
.. code-block:: python
401+
:linenos:
402+
403+
import warnings
404+
warnings.simplefilter('ignore')
405+
# $ python3 -Wi sample.py
406+
# $ python3 -Wignore sample.py
407+
408+
409+
print('-------Before #01-------')
410+
warnings.warn('#01')
411+
print('-------After #01-------')
412+
413+
::
414+
415+
-------Before #01-------
416+
-------After #01-------
417+
418+
419+
.. code-block:: python
420+
:linenos:
421+
422+
import warnings
423+
warnings.simplefilter('ignore', DeprecationWarning)
424+
# $ python3 -Wignore::DeprecationWarning sample.py
425+
# $ python3 -Wi::DeprecationWarning sample.py
426+
427+
428+
print('-------Before #02-------')
429+
warnings.warn('#02')
430+
print('-------After #02-------')
431+
432+
print('-------Before #03-------')
433+
warnings.warn('#03', DeprecationWarning)
434+
print('-------After #03-------')
435+
436+
::
437+
438+
-------Before #02-------
439+
sample.py:8: UserWarning: #02
440+
warnings.warn('#02')
441+
-------After #02-------
442+
-------Before #03-------
443+
-------After #03-------
444+
445+
446+
.. code-block:: python
447+
:linenos:
448+
449+
import warnings
450+
warnings.simplefilter('error')
451+
# $ python3 -We sample.py
452+
# $ python3 -Werror sample.py
453+
454+
455+
print('-------Before #04-------')
456+
warnings.warn('#04')
457+
print('-------After #04-------')
458+
459+
460+
::
461+
462+
-------Before #04-------
463+
Traceback (most recent call last):
464+
File "sample.py", line 8, in <module>
465+
warnings.warn('#04')
466+
UserWarning: #04
467+
468+
469+
.. tip::
470+
471+
اعمال Filter در زمان اجرای اسکریپت نیز با استفاده از کلید ``W-`` ممکن می‌باشد [`اسناد پایتون <https://docs.python.org/3/using/cmdline.html#cmdoption-w>`__] که در هر نمونه کد، معادل دستور اجرای پایتون نیز به صورت کامنت درج شده است.
472+
473+
474+
.. tip::
475+
476+
همانند Exceptionها می‌توانید انواع Warning خود را ایجاد نمایید. برای این منظور تنها کافی است یک کلاس ایجاد نمایید که از کلاس ``Warning`` یا یکی از subclassهای آن ارث‌بری داشته باشد.
477+
478+
.. note::
479+
480+
این بخش به دلیل وابستگی مبحث Warning با مبحث مهم Exception در زبان‌برنامه‌نویسی پایتون و صرفا به منظور آشنایی خوانندگان با همچنین قابلیتی در این زبان تهیه شده است. ماژول ``warnings`` امکانات گسترده‌تری را فراهم می‌آورد که پرداختن به تمام آن‌ها خارج از حوصله این درس می‌بود، بنابراین علاقه‌مندان برای مطالعه بیشتر می‌توانند به مستندات رسمی پایتون مراجعه نمایند.
245481

246482

247483

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.