Python - Decorators - Dynamically Alter The Functionality Of Your Functions
** Decorators - Dynamically Alter The Functionality Of Your Functions
==========================================
def outer_function():
message = 'Hi'
def inner_function():
print(message)
return inner_function()
outer_function()
---------------------------------
Hi
---------------------------------
==========================================
# Decorators
def outer_function():
message = 'Hi'
def inner_function():
print(message)
return inner_function
outer_function()
---------------------------------
nothing
---------------------------------
==========================================
def outer_function():
message = 'Hi'
def inner_function():
print(message)
return inner_function
my_func = outer_function()
my_func()
my_func()
my_func()
---------------------------------
Hi
Hi
Hi
---------------------------------
==========================================
def outer_function(msg):
message = msg
def inner_function():
print(message)
return inner_function
hi_func = outer_function('Hi')
bye_func = outer_function('Bye')
hi_func()
bye_func()
---------------------------------
Hi
Bye
---------------------------------
==========================================
def outer_function(msg):
def inner_function():
print(msg)
return inner_function
hi_func = outer_function('Hi')
bye_func = outer_function('Bye')
hi_func()
bye_func()
---------------------------------
Hi
Bye
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function():
return original_function()
return wrapper_function
def display():
print('display function ran')
decorated_display = decorator_function(display)
decorated_display()
---------------------------------
display function ran
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function():
print('wrapper executed this befor'.format(original_function.__name__))
return original_function()
return wrapper_function
def display():
print('display function ran')
decorated_display = decorator_function(display)
decorated_display()
---------------------------------
wrapper executed this befor
display function ran
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function():
print('wrapper executed this befor'.format(original_function.__name__))
return original_function()
return wrapper_function
@decorator_function
def display():
print('display function ran')
display()
---------------------------------
wrapper executed this befor
display function ran
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function():
print('wrapper executed this befor'.format(original_function.__name__))
return original_function()
return wrapper_function
@decorator_function
def display():
print('display function ran')
def display_info(name, age):
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('John', 25)
---------------------------------
display_info ran with arguments (John, 25)
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function():
print('wrapper executed this befor'.format(original_function.__name__))
return original_function()
return wrapper_function
@decorator_function
def display():
print('display function ran')
@decorator_function
def display_info(name, age):
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('John', 25)
---------------------------------
display_info('John', 25)
TypeError: wrapper_function() takes 0 positional arguments but 2 were given
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function(*args, **kwargs):
print('wrapper executed this befor'.format(original_function.__name__))
return original_function(*args, **kwargs)
return wrapper_function
@decorator_function
def display():
print('display function ran')
@decorator_function
def display_info(name, age):
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('John', 25)
display()
---------------------------------
wrapper executed this befor
display_info ran with arguments (John, 25)
wrapper executed this befor
display function ran
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function(*args, **kwargs):
print('wrapper executed this befor'.format(original_function.__name__))
return original_function(*args, **kwargs)
return wrapper_function
class decorator_class(object):
def __init__(self, original_function):
self.original_function = original_function
def __call__(self, *args, **kwargs):
print('call method executed this before {}'.format(self.original_function.__name__))
return self.original_function(*args, **kwargs)
@decorator_class
def display():
print('display function ran')
@decorator_class
def display_info(name, age):
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('John', 25)
display()
---------------------------------
call method executed this before display_info
display_info ran with arguments (John, 25)
call method executed this before display
display function ran
---------------------------------
==========================================
def decorator_function(original_function):
def wrapper_function(*args, **kwargs):
print('wrapper executed this befor'.format(original_function.__name__))
return original_function(*args, **kwargs)
return wrapper_function
@decorator_function
def display():
print('display function ran')
@decorator_function
def display_info(name, age):
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('John', 25)
display()
---------------------------------
wrapper executed this befor
display_info ran with arguments (John, 25)
wrapper executed this befor
display function ran
---------------------------------
==========================================
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
@my_logger
def display_info(name, age):
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('John', 25)
---------------------------------
display_info ran with arguments (John, 25)
-------display_info.log---------------
INFO:root:Ran with args: ('John', 25), and kwargs: {}
---------------------------------
==========================================
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
@my_logger
def display_info(name, age):
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('Hank', 30)
---------------------------------
display_info ran with arguments (Hank, 30)
-------display_info.log---------------
INFO:root:Ran with args: ('John', 25), and kwargs: {}
INFO:root:Ran with args: ('Hank', 30), and kwargs: {}
---------------------------------
==========================================
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
import time
@my_timer
def display_info(name, age):
time.sleep(1)
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('Hank', 30)
---------------------------------
display_info ran with arguments (Hank, 30)
display_info ran in: 1.0000507831573486 sec
---------------------------------
==========================================
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
import time
@my_timer
@my_logger
def display_info(name, age):
time.sleep(1)
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('Hank', 30)
---------------------------------
display_info ran with arguments (Hank, 30)
wrapper ran in: 1.0000500679016113 sec
-------display_info.log---------------
INFO:root:Ran with args: ('John', 25), and kwargs: {}
INFO:root:Ran with args: ('Hank', 30), and kwargs: {}
INFO:root:Ran with args: ('Hank', 30), and kwargs: {}
---------------------------------
==========================================
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
import time
@my_logger
@my_timer
def display_info(name, age):
time.sleep(1)
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('Hank', 30)
---------------------------------
display_info ran with arguments (Hank, 30)
display_info ran in: 1.0030512809753418 sec
---------wrapper.log----------------
INFO:root:Ran with args: ('Hank', 30), and kwargs: {}
---------------------------------
==========================================
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
import time
def display_info(name, age):
time.sleep(1)
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info = my_logger(my_timer(display_info))
print(display_info.__name__)
---------------------------------
wrapper
---------------------------------
==========================================
from functools import wraps
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
@wraps(orig_func)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
@wraps(orig_func)
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
import time
@my_timer
@my_logger
def display_info(name, age):
time.sleep(1)
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info = my_timer(display_info)
print(display_info.__name__)
display_info('Hank', 30)
---------------------------------
display_info
display_info ran with arguments (Hank, 30)
display_info ran in: 1.000056505203247 sec
display_info ran in: 1.000056505203247 sec
---------------------------------
==========================================
from functools import wraps
def my_logger(orig_func):
import logging
logging.basicConfig(filename = '{}.log'.format(orig_func.__name__), level = logging.INFO)
@wraps(orig_func)
def wrapper(*args, **kwargs):
logging.info(
'Ran with args: {}, and kwargs: {}'.format(args, kwargs))
return orig_func(*args, **kwargs)
return wrapper
def my_timer(orig_func):
import time
@wraps(orig_func)
def wrapper(*args, **kwargs):
t1 = time.time()
result = orig_func(*args, **kwargs)
t2 = time.time() - t1
print('{} ran in: {} sec'.format(orig_func.__name__, t2))
return result
return wrapper
import time
@my_timer
@my_logger
def display_info(name, age):
time.sleep(1)
print('display_info ran with arguments ({}, {})'.format(name, age))
display_info('Tom', 22)
---------------------------------
display_info ran with arguments (Tom, 22)
display_info ran in: 1.001056432723999 sec
-------display_info.log---------------
INFO:root:Ran with args: ('Tom', 22), and kwargs: {}
---------------------------------