مشخصات مقاله
-
650
-
0.0
-
2676
-
0
-
0
آموزش مدیریت استثناها در پایتون
آموزش مدیریت استثناها در زبان برنامه نویسی پایتون
نوشتن برنامه هایی که استثناهای انتخاب شده را مدیریت کند امکان پذیر است. مثال زیر را ببینید که تا زمان دریافت عدد صحیح معتبر، از کاربر درخواست ورودی می کند.
اما به کاربر این امکان را می دهد که برنامه را قطع کند (با استفاده از کنترل +C و یا هر آنچه که سیستم عامل پشتیبانی می کند). توجه داشته باشید این قطع شدن برنامه که توسط کاربر رخ داده است با اعلام استثنای KeyboardInterrupt شناسانده می شود.
>>> while True:
... try:
... x = int(input("Please enter a number: "))
... break
... except ValueError:
... print("Oops! That was no valid number. Try again...")
...
عبارت try به صورت زیر کار می کند.
- ابتدا، بخش try (عبارات بین دو کلمه کلیدی try و except) اجرا می شود.
- اگر هیچ استثنایی رخ ندهد، از روی بخش except می پرد( این بخش اجرا نمی شود) و اجرای عبارت try تمام می شود.
- اگر در حین اجرای بخش try استثنایی رخ دهد، از اجرای بقیه این بخش صرف نظر می کند. سپس اگر نوع خطای رخ داده با نام خطای نوشته شده پس از کلمه کلیدی except یکسان باشد، بخش except اجرا می شود، و سپس اجرا از پس از عبارت try ادامه می یابد.
- اگر استثنایی رخ دهد که مشابه نام استثنا در بخش except نباشد، به خارج از عبارات بخش try منتقل می شود. اگر هیچ بخش مدیریتی (handler) وجود نداشته باشد، یک استثنای مدیریت نشده رخ داده است و اجرا با پیامی که در بالا نشان داده شده است متوقف می شود.
یک عبارت try ممکن است برای مدیریت استثناهای مختلف، بیشتر از یک بخش except داشته باشد. حداکثر یک بخش مدیریتی اجرا خواهد شد. بخش های مدیریتی، تنها استثناهای رخ داده شده در بخش try مربوطه را مدیریت می کنند، نه در سایر بخش های مدیریتی از عبارت try مشابه. یک بخش استثنا ممکن است چندین استثنا را در قالب یک چندتایی پرانتز دار نام ببرد. برای مثال:
... except (RuntimeError, TypeError, NameError):
... pass
یک کلاس درون یک بخش except ، با یک استثنا سازگار است، اگر همان کلاس مشابه یا یک کلاس پایه باشد. (اما عکس آن صادق نیست- یک بخش except که یک کلاس مشتق شده را لیست کرده است با یک کلاس پایه سازگار نیست). برای مثال، کد زیر B ,C ,D را به این ترتیب چاپ می کند.
class B(Exception):
pass
class C(B):
pass
class D(C):
pass
for cls in [B, C, D]:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
توجه داشته باشید که اگر بخش های except معکوس شوند ( اول except B باشد)، B,B,B چاپ می شد—اولین بخش except فعال شده است.
آخرین بخش except ممکن است نام استثنا(ها) را حذف کند. از این قابلیت با احتیاط بسیار استفاده کنید، زیرا پنهان شدن یک خطای واقعی برنامه نویسی از این طریق به سادگی امکان پذیر است. همچنین از آن می توان برای چاپ یک پیام خطا و اعلام دوباره آن استثنا استفاده کرد (همچنین اجازه به فراخواننده برای مدیریت استثنا).
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
عبارت try … except دارای یک بخش else اختیاری است که در صورت وجود باید از همه بخش های استثنا پیروی کند. این برای کدی که بخش try آن استثنایی اعلام نکرده و باید اجرا شود، مفید است. برای مثال:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except OSError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
استفاده از بخش else بهتر از افزودن کد اضافی به بخش try است، زیرا آن از گرفتن تصادفی استثنایی که توسط کدی که با عبارت try … except محافظت می شود، جلوگیری میکند. زمانی که یک استثنا رخ می دهد، ممکن است یک مقدار وابسته داشته باشد، که به عنوان آرگومان استثنا نیز شناخته می شود.
حضور و نوع آرگومان به نوع استثنا بستگی دارد. بخش except ممکن است یک متغیر را بعد از نام استثنا مشخص کند. متغیر به یک نمونه استثنا (exception instance) محدود است و آرگومان ها در instance.args ذخیره می شوند.
. برای سادگی، نمونه استثنا __str__() را تعریف می کند، بنابراین آرگومان ها می توانند مستقیما بدون نیاز به ارجاع به .args چاپ شوند. همچنین ممکن است ابتدا پیش از اعلام یک استثنا، مقدار دهی اولیه شود و هر ویژگی دلخواه به آن اضافه شود.
>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
اگر یک استثنا دارای آرگومان باشد، آنها همانند بخش آخر (‘detail’) پیام برای استثناهای مدیریت نشده، چاپ می شوند. بخش مدیریت استثنا فقط استثناها را در صورت وقوع فوری در بخش try مدیریت نمیکند، بلکه اگر درون توابع بخش try فراخوانی شوند یا حتی مستقیما در آن توابع رخ دهند نیز مدیریت می شوند. برای مثال:
>>> def this_fails():
... x = 1/0
...
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print('Handling run-time error:', err)
...
Handling run-time error: division by zero