Синтактично правилен код не ни гарантира, че програмата ни е валидна!
Errors(Грешки), хванати по време на изпълнение на кода, наричаме Exceptions(Изключения)!
Тип на грешката:
Пример: TypeError, ValueError, ImportError, etc.
Описание на грешката:
Пример: invalid literal for int() with base 10: 'Some wild string'
Къде е възникнала :
Пример: File "<stdin>", line 1, in <module>
>>> magic_number = 41 + '1'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Enter your age: 23
23
Enter your age: 44
44
Enter your age: ff
Traceback (most recent call last):
File "handling_exceptions.py", line 7, in <module>
age = int(input("Enter your age: "))
ValueError: invalid literal for int() with base 10: 'ff'
while True:
age = int(input("Enter your age: "))
print(age)
Enter your age: 23
23
Enter your age: dd
Invalid number
Enter your age: 44
44
Enter your age: hey
Invalid number
while True:
try:
age = int(input("Enter your age: "))
print(age)
except ValueError:
print("Invalid number")
try:
pass # do something
except Exception:
pass # catch one or more exceptions
else:
pass # if try part is executed, execute 'else' part of the block
finally:
pass # part that executes after everything
with open('some_file.txt', 'r+') as fn:
data = fn.read()
print(data)
i = 0
while i < 10:
file_new_data = input('Enter information: ')
fn.write(file_new_data)
i += 1
Обект, който дефинира контекста в with блока, по време на изпълнение на кода
# set things up
try:
# do something
pass
finally:
# tear things down
pass
class some_context_manager:
def __enter__(self):
# set things up
pass
def __exit__(self, type, value, traceback):
# tear things down
pass
with some_context_manager() as thing:
# some code
pass
__enter__(self) и __exit__(self) наричаме Guardians на Context Manager-a
class Log:
def __init__(self, filename):
self.filename = filename
self.file_handler = None
def log(self, text):
self.file_handler.write(text + '\n')
def __enter__(self):
print('__enter__')
self.file_handler = open(self.filename, 'r+')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('__exit__')
self.file_handler.close()
return True
with Log('log_file.txt') as logger:
print('In with block')
logger.log('Some log')
logger.log('Another log')
# Result
# __enter__
# In with block
# __exit__
with Log('log_file1.txt') as l1:
l1.log('In file 1')
with Log('log_file2.txt') as l2:
l2.log('In file 2')
Съществува и nested with block
with Log('log_file1.txt') as l1, Log('log_file2.txt') as l2:
l1.log('In file 1')
l2.log('In file 2')
from contextlib import contextmanager
@contextmanager
def open_file(filename):
file_handler = open(filename)
yield file_handler
file_handler.close()
with open_file('some_file.txt') as f:
print(f.read())
Чрез декоратор от библиотеката можем да създадем Context Manager!
from contextlib import contextmanager
@contextmanager
def context_manager():
print('Entering')
try:
yield 'Yielded value'
print('Exiting successfully')
except Exception as exc:
print('Excepting..', exc)
finally:
print('Finally..')
with context_manager() as cm:
print('Inside context manager')
print('Return value of context manager: ', cm)
raise Exception('Smt went wrong.')