import jars
ERROR = -1
SUCCESS = 0
def the_winter_is_coming():
jar = jars.Jar()
if jar.clean() == jars.ERROR:
print("Something went terribly wrong!")
return ERROR
if jar.fill('python juice') == jars.ERROR:
print("Something went terribly wrong!")
return ERROR
if jar.close() == jars.ERROR:
print("Something went terribly wrong!")
return ERROR
return SUCCESS
import jars
def the_winter_is_coming():
try:
jar = jars.Jar()
jar.clean()
jar.fill('python juice')
jar.close()
except jars.Error:
print("Something went terribly wrong!")
try
# блок
except Изключение
# блок за хващане и обработка на някое от описаните изключения
…
except ДругоИзключение
# блок за хващане и обработка на някое от описаните изключения
except
# блок за хващане и обработка на което и да е изключение(== except BaseException)
else
# блок изпълняващ се, ако не е възникнала изключителна ситуация
finally
# блок изпълнява се винаги
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- ArithmeticError
+-- ...
+-- AssertionError
+-- AttributeError
+-- NameError
+-- UnboundLocalError
+-- OSError
+-- ...
+-- RuntimeError
+-- NotImplementedError
+-- SyntaxError
+-- IndentationError
+-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
+-- ...
+-- Warning
+-- ...
try:
x = [] / 4
except TypeError as data:
print(data)
Какво ще има в data, зависи от самото изключение, но е прието всички да връщат годна за отпечатване стойност, ако се дадат като аргументи на str или repr.
try:
doomed()
except (NameError, TypeError) as data:
print(data)
except (MyError, YourError):
print("Opps! This shouldn't have hapenned...")
except:
print("Unknown exception.")
else:
print("It's my happy day!")
С празен except прихващаме изключения, които не са били хванати до момента. Трябва да бъде поставен след всички други except-и.
file = open('data.txt')
try:
e.load_info(file)
except IOError as data:
print("Couldn't read from file:", data)
except (e.BadDataError, e.InternalError) as data:
print('Loading failed:', data)
else:
print('Data loaded successfully from file.')
finally:
file.close()
Ако присъства, finally стои винаги най-отдолу.
class WinterError(Exception):
def __init__(self):
self.issuer, self.message = 'You are', 'NOT PREPARED!!11!едно!1'
class WildlingError(WinterError):
def __init__(self):
super().__init__()
self.message = 'We are going to light the biggest fire the North has ever seen!1!!'
class YgetteError(WildlingError):
def __init__(self):
super().__init__()
self.message = 'You know nothing, John Snow!'
class WhiteWalker(WinterError):
def __init__(self):
super().__init__()
self.message = 'Rawr!'
def winter_is_coming(): raise WinterError
def winter_is_here(): raise WhiteWalker()
try:
bender.live_a_day()
except BenderError:
bender.boned = True
# Бендър не може да се оправя с това, нека тези отгоре да се грижат
raise
Няколко неща, за които може да ползваме изключения:
обработка на грeшки:
безусловно извършване на заключителни действия — finally
Искаме да обърнем реда на редовете на файл?
try:
source_file = open(src, 'r')
buffer = []
try:
buffer = source_file.readlines()
finally:
source_file.close()
target_file = open(target, 'w')
try:
for line in reversed(buffer):
target_file.write(line)
finally:
target_file.close()
except IOError:
print("Tough luck, junior")
buffer = []
try:
with open(src) as source_file:
buffer = source_file.readlines()
with open(target) as target_file:
for line in reversed(buffer):
target_file.write(line)
except IOError:
print("Much better, now, ain't it?")
with гарантира, че файлът ще бъде затворен автоматично.
with израз [as име]:
блок
with open('/etc/passwd') as source_file:
buffer = source_file.readlines()
print('Done!')
е същото като
source_file = open('/etc/passwd').__enter__()
try:
buffer = source_file.readlines()
source_file.__exit__(None, None, None)
except Exception:
source_file.__exit__(*sys.exc_info())
print('Done!')
class Manager:
def __enter__(self):
print("I've been entered!")
return 42
def __exit__(self, type, value, traceback):
print("I've been exited!")
with Manager() as something:
print("Am I inside?")
print(something)
# I've been entered!
# Am I inside?
# 42
# I've been exited!
with foo() as f, bar() as b:
...
е същото като
with foo() as f:
with bar() as b:
...
Вграденият модул contextlib ни предлага три много полезни Context Manager-а:
contextlib.closing вика метода close на обекта, с който работим, след изпълнение на блока:
class closing(object):
def __init__(self, thing): self.thing = thing
def __enter__(self): return thing
def __exit__(self, type, value, traceback):
self.thing.close()
...и ви позволява да пишете следното:
from contextlib import closing
from urllib.request import urlopen
with closing(urlopen('http://www.python.org')) as page:
for line in page:
print(line)