# -*- coding:utf-8 -*-
# 學習裝飾器的一些常用場景
from functools import wraps
def decorator_name(f):
@wraps(f)
def decorated(*arg, **kwargs):
if not can_run:
return('Function will not run')
return f(*arg, **kwargs)
return decorated
@decorator_name
def func():
return('Function is running')
#can_run = True
#print(func())
can_run = False
print(func())
# 小結:@wraps接受一個函數來進行裝飾,并加入了複制函數名稱、注釋文檔、參數清單等功能。
# 這可以讓我們在裝飾器裡面通路在裝飾之前的函數的屬性
"""
裝飾器使用場景-授權(Authorization)
"""
# 裝飾器能有助于檢查某個人是否被授權去使用一個web應用的端點(endpoint)。它們被大量使用于
# Flask和Django web架構中。這裡是一個例子來使用基于裝飾器的授權
from functools import wraps
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = requests.authorization
if not auth or not check_auth(auth.username, auth.password):
authenticate()
return f(*args, **kwargs)
return decorated
"""
裝飾器使用場景-日志(Logging)
"""
# 日志是裝飾器運用的另一個亮點,這是個例子
from functools import wraps
def logit(func):
@wraps(func)
def with_logging(*args, **kwargs):
print(func.__name__ + "was called")
return func(*args, **kwargs)
return with_logging
@logit
def addition_func(x):
"""Do some math"""
return x + x
result = addition_func(4)
print(result)
"""
帶參數的裝飾器-在函數中嵌入裝飾器
"""
from functools import wraps
def logit1(logfile='out.log'):
def logging_decorator(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# 打開logfile,并寫入内容
with open(logfile, 'a') as opened_file:
# 現在将日志列印到指定的logfile
opened_file.write(log_string + '\n')
return func(*args, **kwargs)
return wrapped_function
return logging_decorator
@logit1(logfile='fun2.log')
def myfun1():
pass
myfun1()
"""
裝飾器類
"""
from functools import wraps
class logit2(object):
def __init__(self, logfile='out.log'):
self.logfile = logfile
def __call__(self, func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# 打開logfile,并寫入内容
with open(self.logfile, 'a') as opened_file:
# 現在将日志列印到指定的logfile
opened_file.write(log_string + '\n')
# 現在,發送一個通知
self.notify()
return func(*args, **kwargs)
return wrapped_function
def notify(self):
print('logit隻打日志,不做别的')
pass
@logit2()
def myfunc2():
print('調用通知')
print('------')
myfunc2()
# 現在,我們給logit建立子類,來添加email的功能
class email_logit(logit2):
"""
一個logit的實作版本,可以在函數調用時發送email給管理者
"""
def __init__(self, email='[email protected]', *args, **kwargs):
self.email = email
super(email_logit, self).__init__(*args, **kwargs)
def notify(self):
# 發送一封email到self.email
# 這裡就不做實作了
pass
作者:ReluStarry