exceptions & context managers

$> ls -l
total 4
-rw-rw-r-- 1 ... 6 ноя 20 16:49 hello.txt
$> cat hello.txt 
hello
$> echo $?
0
$> cat kek.txt
cat: kek.txt: No such file or directory
$> echo $?
1
// golang
varFoo, err := GetFoo()
if err != nil {
    return err
}
# python: result

from returns.result import (
    Result, Success, Failure,
)

def find_user(user_id: int):
    user = User.objects.filter(id=user_id)
    if user.exists():
        return Success(user[0])
    return Failure('User was not found')
user_search_result = find_user(1)
# => Success(User{id: 1, ...})

user_search_result = find_user(0)
# => Failure('User was not found')
try:
    # some danger stmt
    ...
except ValueError:
    # if ValueError (or its subclass) raised
    ...
except Exception:
    # if Exception (or its subclass) raised
    ...
else:
    # if no exception raised
    ...
finally:
    # runs anyway
    ...
def func():
    try:
        return 1
    finally:
        return 2

      
print(func())
# 2
def do_and_apologise(data, key):
    try:
        return data[key]
    except KeyError:
        return None
def ask_and_do(data, key):
    if key in data:
        return data[key]
    return None
%timeit do_and_apologise({}, 1)
190 ns ± 2.28 ns per loop
%timeit ask_and_do({}, 1)
76 ns ± 2.91 ns per loop
class MyContextManager:
    def __enter__(self):
        print('entering context')
      
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f'exiting context with {exc_type}')
# entering context
# inside context
# exiting context with None
with MyContextManager():
    print('inside context')
class MyContextManager:
    def __enter__(self):
        print('entering context')
      
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f'exiting context with {exc_type}')
# entering context
# exiting context with <class 'ZeroDivisionError'>
      1 with MyContextManager():
----> 2     infinity = 1 / 0
      3     print(f'infinity is {infinity}')
      4 

ZeroDivisionError: division by zero
with MyContextManager():
    infinity = 1 / 0
    print(f'infinity is {infinity}')
class MyContextManager:
    def __enter__(self):
        print('entering context')
      
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f'exiting context with {exc_type}')
        return True
# entering context
# exiting context with <class 'ZeroDivisionError'>
with MyContextManager():
    infinity = 1 / 0
    print(f'infinity is {infinity}')
class MyContextManager:
    def __init__(self, name):
        self._name = name
  
    def __enter__(self):
        print(f'entering context: {self._name}')
      
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f'exiting context {self._name} '
              f'with {exc_type}')
with (
    MyContextManager('cm1'),
    MyContextManager('cm2'),
):
    print('inside')
with (
    MyContextManager('cm1'),
    MyContextManager('cm2'),
):
    print('inside')
# entering context: cm1
# entering context: cm2
# inside
# exiting context cm2 with None
# exiting context cm1 with None
from contextlib import ExitStack
filenames = ['f1.txt', 'f2.txt', ...]
with ExitStack() as stack:
    files = [
        stack.enter_context(open(filename))
        for filename in filenames
    ]
    for f in zip(*files):
        print(*f)
with open('f1.txt') as f1, open('f2.txt') as f2:
    for i1, i2 in zip(f1, f2):
        print(i1, i2)
import contextlib

@contextlib.contextmanager
def my_context_manager(name):
    print(f'entering {name}')
    yield
    print(f'exiting {name}')
# entering cm
# inside
# exiting cm
with my_context_manager('cm'):
    print('inside')

09 exceptions & context managers

By persi

09 exceptions & context managers

  • 117