Функции


In [1]:
from datetime import datetime


def get_seconds():
    """Return current seconds"""
    return datetime.now().second


get_seconds()


Out[1]:
13

In [2]:
help(get_seconds)


Help on function get_seconds in module __main__:

get_seconds()
    Return current seconds


In [3]:
get_seconds.__doc__


Out[3]:
'Return current seconds'

In [4]:
get_seconds.__name__


Out[4]:
'get_seconds'

In [ ]:


In [5]:
def split_tags(tag_string):
    tag_list = []
    for tag in tag_string.split(','):
        tag_list.append(tag.strip())
        
    return tag_list


split_tags('functions, classes, OOP, inheritance, methods')


Out[5]:
['functions', 'classes', 'OOP', 'inheritance', 'methods']

In [ ]:


In [6]:
split_tags()


---------------------------------------------------------
TypeError               Traceback (most recent call last)
<ipython-input-6-866c00aba286> in <module>()
----> 1 split_tags()

TypeError: split_tags() missing 1 required positional argument: 'tag_string'

In [ ]:


In [7]:
def add(x: int, y: int) -> int:
    return x + y


print(add(10, 11))
print(add('still ', 'works'))


21
still works

In [ ]:

Напишите функцию, которая находит медиану переданного списка


In [ ]:


In [ ]:


In [ ]:

По ссылке или по значению?


In [11]:
def extender(source_list, extend_list):
    source_list.extend(extend_list)
    

values = [1, 2, 3]
extender(values, [4, 5, 6])

print(values)


[1, 2, 3, 4, 5, 6]

In [12]:
def replacer(source_tuple, replace_with):
    source_tuple = replace_with
    

user_info = ('Guido', '31/01')
replacer(user_info, ('Larry', '27/09'))

print(user_info)


('Guido', '31/01')

In [ ]:
# mutable vs immutable

Именованные аргументы


In [13]:
def say(greeting, name):
    print('{} {}!'.format(greeting, name))
    

say('Hello', 'Kitty')
say(name='Kitty', greeting='Hello')


Hello Kitty!
Hello Kitty!

Область видимости


In [15]:
result = 0

def increment():
    result = 1
    return result

result = increment()


1

In [ ]:
# global & nonlocal

Аргументы по умолчанию


In [17]:
def greeting(name='it\'s me...'):
    print('Hello, {}'.format(name))
    
    
greeting('Kitty')

print(greeting.__defaults__)


Hello, Kitty
("it's me...",)

In [18]:
def append_one(iterable=[]):
    iterable.append(1)
    
    return iterable


print(append_one([1]))


[1, 1]

In [19]:
print(append_one())
print(append_one())


[1]
[1, 1]

In [20]:
print(append_one.__defaults__)


([1, 1],)

In [21]:
def function(iterable=None):
    if iterable is None:
        iterable = []
    

def function(iterable=None):
    iterable = iterable or []

Звездочки


In [26]:
def printer(*args):
    print(type(args))
    
    for argument in args:
        print(argument)


printer(1, 2, 3, 4, 5)


<class 'tuple'>
1
2
3
4
5

In [27]:
name_list = ['John', 'Bill', 'Amy', 'Jane']
printer(*name_list)


<class 'tuple'>
John
Bill
Amy
Jane

In [29]:
def printer(**kwargs):
    print(type(kwargs))
    
    print(kwargs.keys())
        
        
printer(a=10, b=11)


<class 'dict'>
dict_keys(['a', 'b'])

In [30]:
payload = {
    'user_id': 117,
    'feedback': {
        'subject': 'Registration fields',
        'message': 'There is no country for old men'
    }
}

printer(user_id=117, feedback={
    'subject':. ...
})


<class 'dict'>
dict_keys(['user_id', 'feedback'])

Функциональное программирование


In [31]:
def caller(func, params):
    return func(*params)


def printer(name, origin):
    print('I\'m {} of {}!'.format(name, origin))
    
    
caller(printer, ['Moana', 'Motunui'])


I'm Moana of Motunui!

In [52]:
caller(lambda x: x ** 3, [10])


Out[52]:
1000

In [ ]:


In [32]:
def get_multiplier():
    def inner(a, b):
        return a * b
    return inner
    
    
multiplier = get_multiplier()
multiplier(10, 11)


Out[32]:
110

In [33]:
print(multiplier.__name__)


inner

In [39]:
def get_multiplier(number):
    def inner(a):
        return a * number
    return inner


ten = get_multiplier(10)
two = get_multiplier(2)

two(2), ten(9)


Out[39]:
(4, 90)

map, filter, lambda


In [43]:
def squarify(a):
    return a ** 2


list(map(squarify, [1, 2, 3, 4]))


Out[43]:
[1, 4, 9, 16]

In [ ]:
squared_list = []

for number in range(5):
    squared_list.append(squarify(number))
    
print(squared_list)

In [45]:
def is_positive(a):
    return a > 0


list(filter(is_positive, [-3, 4, 5, -10]))


Out[45]:
[4, 5]

In [ ]:
positive_list = []

for number in range(-2, 3):
    if is_positive(number):
        positive_list.append(number)
        
print(positive_list)

In [47]:
list(map(lambda x: x ** 2, range(5)))


Out[47]:
[0, 1, 4, 9, 16]

In [46]:
l = lambda x: x ** 2


Out[46]:
function

In [48]:
list(filter(lambda x: x > 0, range(-2, 3)))


Out[48]:
[1, 2]

Написать функцию, которая превращает список чисел в список строк


In [55]:
def stringify(numbers):
    return list(map(str, numbers))


stringify([1, 2, 3, 4])


Out[55]:
['1', '2', '3', '4']

functools


In [56]:
from functools import reduce


def multiply(a, b):
    return a * b


reduce(multiply, [1, 2, 3, 4, 5])


Out[56]:
120

In [57]:
reduce(lambda x, y: x * y, range(1, 5))


Out[57]:
24

In [58]:
from functools import partial


def greeter(person, greeting):
    return '{}, {}!'.format(greeting, person)


hier = partial(greeter, greeting='Hi')
helloer = partial(greeter, greeting='Hello')


print(hier('brother'))
print(helloer('sir'))


Hi, brother!
Hello, sir!

Списочные выражения


In [59]:
square_list = []
for number in range(10):
    square_list.append(number ** 2)
    
print(square_list)


[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [60]:
square_list = [number ** 2 for number in range(10)]
print(square_list)


[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [61]:
even_list = []
for number in range(10):
    if number % 2 == 0:
        even_list.append(number)
        
print(even_list)


[0, 2, 4, 6, 8]

In [63]:
even_list = [num for num in range(10) if num % 2 == 0]

print(even_list)


[0, 2, 4, 6, 8]

In [64]:
square_map = {number: number ** 2 for number in range(5)}

print(square_map)


{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

In [65]:
reminders_set = {num % 10 for num in range(100)}

print(reminders_set)


{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

In [66]:
print(type(number ** 2 for number in range(5)))


<class 'generator'>

In [69]:
num_list = range(7)
squared_list = [x ** 2 for x in num_list]
squared_list = squared_list[:6]

list(zip(num_list, squared_list))


Out[69]:
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]

Декораторы


In [70]:
def decorator(func):
    return func


@decorator
def decorated():
    print('Hello!')

In [ ]:
decorated = decorator(decorated)

In [ ]:


In [71]:
def decorator(func):
    def new_func():
        pass
    return new_func


@decorator
def decorated():
    print('Hello!')
    
    
decorated()

In [72]:
print(decorated.__name__)


new_func

Написать декоратор, который записывает в лог результат декорируемой функции


In [ ]:
def f(func):
    pass


def g():
    pass


g = f(g)

In [ ]:


In [ ]:


In [ ]:


In [96]:
from functools import wraps


def logger(func):

    @wraps(func)
    def inner(*args, **kwargs):
        result = func(*args, **kwargs)
        with open('log.txt', 'w') as f:
            f.write(str(result))
        return result
    return inner
    
    
@logger
def summator(numbers):
    return sum(numbers)


@logger
def multiply(a, b):
    return a * b

In [97]:
multiply.__name__


Out[97]:
'multiply'

* Написать декоратор с параметром, который записывает лог в указанный файл


In [ ]:
def logger(filename):
    def decorator(func):

        def inner(*args):
            result = func(*args)
            with open(filename, 'w') as f:
                f.write(str(result))

            return result

        return inner
    return decorator



@logger('new_log.txt')
def summator(numbers):
    return sum(numbers)


# summator = logger('new_log.txt')(summator)

In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [98]:
def first_decorator(func):
    def wrapped():
        print('Inside first_decorator product')
        return func()
    return wrapped


def second_decorator(func):
    def wrapped():
        print('Inside second_decorator product')
        return func()
    return wrapped

In [99]:
@first_decorator
@second_decorator
def decorated():
    print('Finally called...')
    
    
# decorated = first_decorator(second_decorator(decorated))
    

decorated()


Inside first_decorator product
Inside second_decorator product
Finally called...

In [ ]:


In [101]:
def bold(func):
    def wrapped():
        return "<b>" + func() + "</b>"
    return wrapped


def italic(func):
    def wrapped():
        return "<i>" + func() + "</i>"
    return wrapped


@bold
@italic
def hello():
    return "hello world"


# hello = bold(italic(hello))


print(hello())


<b><i>hello world</i></b>

Классы


In [106]:
isinstance([], list)


Out[106]:
True

In [ ]:


In [108]:
class DeadSimple:
    pass


obj = DeadSimple()

In [ ]:

Создание объекта


In [110]:
class User:    
    def __init__(self, name, email):
        self.name = name
        self.email = email
        
        
bob = User('bob', 'bob@mail.ru')
alice = User('alice', 'alice@mail.ru')


Out[110]:
'bob@mail.ru'

In [111]:


In [115]:
class Singleton:
    obj = None
    def __new__(cls, *args, **kwargs):
        if cls.obj is None:
            cls.obj = object.__new__(cls, *args, **kwargs)
        
        return cls.obj
    

s = Singleton()
print(s)

new_s = Singleton()
print(new_s)

print(Singleton.obj)


<__main__.Singleton object at 0x10f2ddcf8>
<__main__.Singleton object at 0x10f2ddcf8>
<__main__.Singleton object at 0x10f2ddcf8>

In [ ]:


In [116]:
class ToBeDeleted:
    def __del__(self, *args, **kwargs):
        print('I\'m gone')
    
    
obj = ToBeDeleted()
del obj


I'm gone

Атрибуты


In [119]:
class News:
    importance = 25

    ...


class Blog:
    importance = 17
    
    def __init__(self, name, moderator):
        self.name = name
        self.moderator = moderator

        
lala = Blog('Lalala', 'alice@mail.ru')
lala.importance


Out[119]:
17

In [ ]:


In [123]:
# lala.importance = 18
# Blog.importance == lala.importance

print(lala.__dict__)


{'name': 'Lalala', 'moderator': 'alice@mail.ru', 'importance': 18}

In [ ]:
news.importance

In [124]:
getattr(news, 'name')


Out[124]:
'Lalala'

In [ ]:
setattr(news, 'name', 'News!')
news.name

In [ ]:

Name Mangling или "приватные" атрибуты


In [125]:
class Storage:
    def __init__(self, amount):
        self.__amount = amount
        
    def _calculate():
        pass
        

storage = Storage(100)
storage.__amount


---------------------------------------------------------
AttributeError          Traceback (most recent call last)
<ipython-input-125-e4151afdd578> in <module>()
      8 
      9 storage = Storage(100)
---> 10 storage.__amount

AttributeError: 'Storage' object has no attribute '__amount'

In [126]:
storage.__dict__


Out[126]:
{'_Storage__amount': 100}

In [127]:
storage._Storage__amount  # gotcha!


Out[127]:
100

Методы


In [135]:
class User:
    dbtable = 'Users.User'
    def __init__(self, name):
        self.name = name
        self.url = self.get_url()

    @staticmethod
    def get_url(self):
        return '/user/'
    
    
alice = User('alice')
bob = User('bob')


---------------------------------------------------------
TypeError               Traceback (most recent call last)
<ipython-input-135-394b17c61e23> in <module>()
     10 
     11 
---> 12 alice = User('alice')
     13 bob = User('bob')

<ipython-input-135-394b17c61e23> in __init__(self, name)
      3     def __init__(self, name):
      4         self.name = name
----> 5         self.url = self.get_url()
      6 
      7     @staticmethod

TypeError: get_url() missing 1 required positional argument: 'self'

In [ ]:


In [ ]:


In [ ]:


In [ ]:

Написать пару классов для своего проекта


In [ ]:
@staticmethod
    def get_url():
        return '/user/'
    
    @property
    def url(self):
        return '/user/'

Наследование


In [147]:
class Publication:
    def __init__(self, title, content):
        self.title = title
        self.content = content
    
    def render(self):
        return '{}{}'.format(self.title, self.content)


class Post(Publication):
    def __init__(self, blog, *args, **kwargs):
        self.blog = blog

        super().__init__(*args, **kwargs)
        
        
post = Post('News', 'Post title', 'Post content')
advert = Advert('Sell', 'Advert title', 'Advert content')

In [155]:
print(post)


<__main__.Post object at 0x10f326780>

In [ ]:
post.render()

In [149]:
isinstance(post, Post)


Out[149]:
True

In [148]:
isinstance(post, Publication)


Out[148]:
True

In [150]:
isinstance(post, object)


Out[150]:
True

In [156]:
isinstance(Publication, object)


Out[156]:
True

In [157]:
issubclass(Publication, object)


Out[157]:
True

In [ ]:

MRO


In [158]:
class Base:
    pass


class A(Base):
    pass


class B(Base):
    pass


A.mro()


Out[158]:
[__main__.A, __main__.Base, object]

In [ ]:


In [161]:
class C(B, A):
    pass


C.__mro__


Out[161]:
(__main__.C, __main__.B, __main__.A, __main__.Base, object)

In [ ]:


In [162]:
c = C()

isinstance(c, A)


Out[162]:
True

In [163]:
isinstance(A(), C)


Out[163]:
False

In [ ]:

Миксины


In [ ]:
class JSONable:
    def to_json(self):
        return json.dumps(self.content)
    
    
class BlogEntry(Publication, JSONable):
    pass


class Advert(Publication)

In [ ]:
class User(JSONable):
    pass

In [ ]:


In [ ]:
user = User()

user.to_json()

In [ ]:

Написать свой контейнер с помощью __getitem__ и __setitem__


In [ ]:

Исключения


In [136]:
def average(num_list):
    return sum(num_list) / len(num_list)

In [ ]:


In [137]:
average([])


---------------------------------------------------------
ZeroDivisionError       Traceback (most recent call last)
<ipython-input-137-07bdd369d5c4> in <module>()
----> 1 average([])

<ipython-input-136-147c485d471c> in average(num_list)
      1 def average(num_list):
----> 2     return sum(num_list) / len(num_list)

ZeroDivisionError: division by zero

In [ ]:


In [138]:
try:
    average([])
except ZeroDivisionError:
    print('Error occurred')


Error occurred

In [ ]:


In [139]:
try:
    average([])
except ZeroDivisionError as e:
    print(e)


division by zero

In [ ]:


In [ ]:
try:
    average([])
except Exception:
    print('Avoid this')

In [ ]:


In [144]:
try:
    average([])
except ZeroDivisionError as e:
    raise e
else:
    print('It\'s OK!')
finally:
    print('Hello there')


Hello there
---------------------------------------------------------
ZeroDivisionError       Traceback (most recent call last)
<ipython-input-144-f1298d7fc2e0> in <module>()
      2     average([])
      3 except ZeroDivisionError as e:
----> 4     raise e
      5 else:
      6     print('It\'s OK!')

<ipython-input-144-f1298d7fc2e0> in <module>()
      1 try:
----> 2     average([])
      3 except ZeroDivisionError as e:
      4     raise e
      5 else:

<ipython-input-136-147c485d471c> in average(num_list)
      1 def average(num_list):
----> 2     return sum(num_list) / len(num_list)

ZeroDivisionError: division by zero

In [ ]:


In [145]:
try:
    average([])
except (ValueError, TypeError, ZeroDivisionError):
    pass

In [ ]:


In [ ]:
try:
    average([])
except ValueError:
    print('Value!')
except ZeroDivisionError:
    print('Zero!')

In [ ]:


In [ ]:
class ParkException(Exception):
    pass

In [ ]:


In [ ]:
raise ValueError('Wrong value')

In [ ]:


In [146]:
try:
    1 / 0
except ZeroDivisionError as e:
    raise ValueError from e


---------------------------------------------------------
ZeroDivisionError       Traceback (most recent call last)
<ipython-input-146-d6b1df7feeac> in <module>()
      1 try:
----> 2     1 / 0
      3 except ZeroDivisionError as e:

ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

ValueError              Traceback (most recent call last)
<ipython-input-146-d6b1df7feeac> in <module>()
      2     1 / 0
      3 except ZeroDivisionError as e:
----> 4     raise ValueError from e
      5 

ValueError: 

assert


In [ ]:
def func(a):
    assert isinstance(a, int)
    
    
func('1')

In [ ]:
assert True, 'I\'m surprised'

In [ ]:
assert False, 'What did you expect?'

In [ ]:


In [ ]:
import random


assert random.randint(1, 5) == 3

print('The End')