Hack Bulgaria
github.com/HackBulgaria
>>> print(This is a print message)
File "<stdin>", line 1
print(This is a print message)
^
SyntaxError: invalid syntax
Най-често срещаните съобщения, които виждаме, докато учим Python, са Error messages. При изпълнението на кода, Python parser-ът е открил грешка. Съобщава ни за нея чрез името й(SyntaxError) и стрелка къде е възникнала.
>>> for i in range(3):
... print(2 * (2 / i))
>>> for i in range(3):
... print(i)
... print(2 * (2 / i))
...
0
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
ZeroDivisionError: division by zero
Възникнала е грешка по време на изпълнение
Синтактично правилен код не ни гарантира, че програмата ни е валидна!
Errors(Грешки), хванати по време на изпълнение на кода, наричаме Exceptions(Изключения)!
>>> Roza + 'Roza'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Roza' is not defined
>>> magic_number = 41 + '1'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> number = int("Some wild string")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'Some wild string'
Тип на грешката:
Пример: TypeError, ValueError, ImportError, etc.
Описание на грешката:
Пример: invalid literal for int() with base 10: 'Some wild string'
Къде е възникнала :
Пример: File "<stdin>", line 1, in <module>
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: rozaaa
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 and 'else' part of the block
finally:
pass # part that executes after everything
try:
f = open('text_file.txt')
except Exception as e:
print('We hit an error: {}'.format(e))
else:
print(f.read())
finally:
if not f.closed:
f.close()
В try клаузата се опитваме да отворим файл,
ако възникне каквато и да е грешка ще я хванем в except чрез класа Exception.
При успешно завършване на try, else частта ще бъде изпълнена. Finally се изпълнява винаги!
try:
f = open('some_file.txt')
except FileNotFoundError:
print('''We hit an error!
This file does not exist!''')
try:
file_name = input('Enter a file name: ')
f = open(file_name)
f.write(10 / 0)
except Exception as e:
print('''Sorry, something went wrong!
You hit an error: {0}'''.format(e))
try:
f = open('roza_custom_file')
Roza = StrangeObject
except (FileNotFoundError, NameError) as e:
print('Something went wrong')
try:
file_name = input('Enter a file name: ')
f = open(file_name)
var = variable
except FileNotFoundError:
print('We hit an error! This file does not exist!')
except NameError as e:
print('You hit an error: {0}'.format(e))
Можем да хванем повече от една грешка
Ако искаме едно и също съобщение да се връща от няколко грешки, ги обединяваме!
# define custom exceptions
class Error(Exception):
"""Base class for other exceptions"""
pass
class InvalidUsernameError(Error):
"""Raised when the username is invalid"""
pass
# our main program
while True:
try:
username = input("Username: "))
if not is_valid(username):
raise InvalidUsernameError
break
except InvalidUsernameError:
print("Invalid username!")
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 logging(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 logfile:
print("In with block")
logfile.logging("Test1 for logfile")
logfile.logging("Test2 for logfile")
# Result
# __enter__
# In with block
# __exit__
with Log("log_file1.txt") as l1:
l1.logging("In file 1")
var = 5
with Log("log_file2.txt") as l2:
l2.logging("Logginf in file 2: {0}".format(var))
Съществува и nested with block
with Log("log_file1.txt") as l1, Log("log_file2.txt") as l2:
l1.logging("In file 1")
var = 5
l2.logging("Logginf in file 2: {0}".format(var))
from contextlib import contextmanager
@contextmanager
def working_with_file(filename):
fn = open(filename)
yield fn
fn.close()
with working_with_file('some_file.txt') as f:
print(f.read())
Чрез декоратор от библиотеката можем да създадем Context Manager!
from contextlib import contextmanager
@contextmanager
def make_context():
print('entering')
try:
yield "Yielding......."
except RuntimeError as err:
print('ERROR: {0}'.format(err))
finally:
print('exiting')
with make_context() as value:
print('inside with statement: {}'.format(value))
By Hack Bulgaria