square_side = 5
def square_area(side):
print(square_side)
print(side ** 2)
square_area(4)
5
16
square_side = 5
def square_area(side):
print(square_side)
print(side ** 2)
square_side = 70
square_area(4)
UnboundLocalError: local variable 'square_side' referenced before assignment
def closure_example():
x = 11
def inner():
print(f'Переменная из замыкания: {x}')
return inner
closure_example()()
Переменная из замыкания: 11
def simple_decorator(func):
def inner():
print('Начало работы декоратора...')
func()
print('Декоратор отработал!')
return inner
def print_hi():
print('Привет, я - функция, которую задекорировали!')
print_hi = simple_decorator(print_hi)
print_hi()
Начало работы декоратора...
Привет, я - функция, которую задекорировали!
Декоратор отработал!
def simple_decorator(func):
def inner():
print('Начало работы декоратора...')
func()
print('Декоратор отработал!')
return inner
@simple_decorator
def print_hi():
print('Привет, я - функция, которую задекорировали!')
print_hi()
Начало работы декоратора...
Привет, я - функция, которую задекорировали!
Декоратор отработал!
def decorate_func_with_params(func):
def inner(*args, **kwargs):
print(f'Декорируем функцию с параметрами: {args}, {kwargs}')
func(*args, **kwargs)
print('Все прошло успешно!')
return inner
@decorate_func_with_params
def adder(*nums):
print(sum(nums))
# Тесты
adder(1)
adder(2, 7, 3)
adder(0, 33, 4, 10, 0)
Декорируем функцию с параметрами: (1,), {}
1
Все прошло успешно!
Декорируем функцию с параметрами: (2, 7, 3), {}
12
Все прошло успешно!
Декорируем функцию с параметрами: (0, 33, 4, 10, 0), {}
47
Все прошло успешно!
def repeater(num_of_repeats=1):
def outer_decorator(func):
def inner_decorator(*args, **kwargs):
if num_of_repeats > 0:
for _ in range(num_of_repeats):
print(func(*args, **kwargs))
else:
print(func(*args, **kwargs))
return inner_decorator
return outer_decorator
@repeater(3)
def print_text(message):
return f'Вам сообщение: {message}'
print_text('Просыпайся!')
Вам сообщение: Просыпайся!
Вам сообщение: Просыпайся!
Вам сообщение: Просыпайся!
class Numerator:
def __init__(self, func):
self.func = func
self.counts = 0
def __call__(self, *args, **kwargs):
self.counts += 1
print(self.counts)
return self.func(*args, **kwargs)
@Numerator
def info_func(*args, **kwargs):
return args, kwargs
# Тесты
print(info_func(2, 3, p=100))
print(info_func(q=10))
print(info_func())
1
((2, 3), {'p': 100})
2
((), {'q': 10})
3
((), {})
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
def person_description(self):
return f'Меня зовут {self.name}, мне {self.age}.'
ivan = Person('Иван', 31)
print(ivan.person_description())
Меня зовут Иван, мне 31.
from time import perf_counter
def timer(unit='s'):
time_mapping = {
's': 1,
'ms': 1000,
'm': 1 / 60,
}
def outer(func):
def inner(*args, **kwargs):
start_time = perf_counter()
func(*args, **kwargs)
end_time = perf_counter()
total_time = round(
(end_time - start_time) * time_mapping.get(unit, 's'),
2
)
print(total_time)
return inner
return outer
@timer('m')
def cube_me(max_number):
for number in range(max_number + 1):
number ** 3
cube_me(10_000_000)
0.05