Python Decorators
Basic Decorator Implementation
import time
def main():
time.sleep(3)
print('Executing main function')
def secondary():
print('Executing secondary function')
def utility():
print('Executing utility function')
def timer_decorator(func_name):
def wrapper():
# Record start time
start = time.time()
func_name()
# Record end time
end = time.time()
print(f'Total execution time: {end - start} seconds')
return wrapper
main = timer_decorator(main)
main()
Handling Function Parameters
import time
def main():
time.sleep(3)
print('Executing main function')
def profile(user_id, **credentials):
print('Executing profile function')
return 'Profile data retrieved'
def utility():
print('Executing utility function')
def timer_decorator(func_name):
def wrapper(*args, **kwargs):
# Record start time
start = time.time()
result = func_name(*args, **kwargs)
# Record end time
end = time.time()
print(f'Total execution time: {end - start} seconds')
return result
return wrapper
main = timer_decorator(main)
main()
profile = timer_decorator(profile)
response = profile('user123', username='jerry', age=18)
print(response)
Standard Decorator Template
def main():
pass
def decorator(func_name):
def wrapper(*args, **kwargs):
# Pre-function functionality
result = func_name(*args, **kwargs)
# Post-function functionality
return result
return wrapper
# Decorators本质上还是函数!
@decorator
def main():
pass
# The decorator principle:
# The decorated object is passed as a parameter to the decorator
Multiple Decorators
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print(f'Execution time: {end - start} seconds')
return res
return wrapper
def authentication_decorator(func):
def wrapper():
username = input('Username: >>>').strip()
password = input('Password: >>>').strip()
if username == 'admin' and password == 'secret':
print('Authentication successful')
func()
else:
print('Invalid credentials')
return wrapper
@authentication_decorator
timing_decorator
def main():
time.sleep(3)
print('Executing main function')
main()
Multiple Layer Decorators
# Predict the execution order of print statements
def outer1(func1):
print('Loading outer1')
def wrapper1(*args, **kwargs):
print('Executing wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1
def outer2(func2):
print('Loading outer2')
def wrapper2(*args, **kwargs):
print('Executing wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2
def outer3(func3):
print('Loading outer3')
def wrapper3(*args, **kwargs):
print('Executing wrapper3')
res3 = func3(*args, **kwargs)
return res3
return wrapper3
@outer1
@outer2
@outer3
def main():
print('Executing main function')
main()
Decorator Preservation Techniques
import time
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper():
start = time.time()
func()
end = time.time()
print(f'Execution time: {end - start} seconds')
return wrapper
def main():
'''This is the main function'''
print('Executing main function')
@decorator
def secondary():
'''This is the secondary function'''
print('Executing secondary function')
help(secondary)
Parameterized Decorators
def authentication_handler(source_type, *args, **kwargs):
def decorator(func):
def wrapper(*args, **kwargs):
username = input('Username: >>>').strip()
password = input('Password: >>>').strip()
# Retrieve credentials based on source type
if source_type == 'file':
print('Retrieving credentials from file')
elif source_type == 'database':
print('Retrieving credentials from database')
elif source_type == 'api':
print('Retrieving credentials from API')
elif source_type == 'ldap':
print('Retrieving credentials from LDAP')
if username == 'admin' and password == 'secret':
print('Authentication successful')
func(source_type, *args, **kwargs)
else:
print('Invalid credentials')
return wrapper
return decorator
@authentication_handler('file', 1, 2, 3, 4, 5)
def profile():
pass
profile('database')