装饰器(Decorators)是Python的一个重要部分。 简单地说: 他们是修改其他函数的功能的函数。
他们有助于让我们的代码更简短, 也更Pythonic( Python范儿)
def a_new_decorator(a_func): def wrapTheFunction(): print("I am doing some boring work before executing a_func()" a_func() print("I am doing some boring work after executing a_func()") return wrapTheFunction def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul sme") a_function_requiring_decoration() #outputs: I am the function which needs some decoration to remove my foul sme a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration) #now a_function_requiring_decoration is wrapped by wrapTheFunction() a_function_requiring_decoration() #outputs: I am doing some boring work before executing a_func() I am the function which needs some decoration to remove my foul smell I am doing some boring work after executing a_func()
用更简洁的方式实现上面类似的修饰器:
from functools import wraps def logits(func): @wraps(func) def with_logging(*args, ** kwargs): print(func.__name__ + "was called") return func(* args, **kwargs) return with_logging @logits def addition_func(x): """Do some math.""" return x + x result = addition_func(4) 输出: addition_funcwas called
带参数的装饰器: 当你使用@my_decorator语法时, 你是在应用一个以单个函数作为参数的一个包
裹函数。 记住, Python里每个东西都是一个对象, 而且这包括函数!
#在函数中嵌入装饰器 def logits(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: opened_file.write(log_string +'\n') return func(*args, **kwargs) return wrapped_function return logging_decorator @logits() #装饰器函数 def myfunc1(): pass myfunc1() 输出:myfunc2was called
装饰器类:
#装饰器类 class logit(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) with open(self.logfile , "a") as opened_file: opened_file.write(log_string + ' \n') #发送一个通知 self.notify() return func(*args, **kwargs) return wrapped_function def notify(self): print("notified") @logit() def myfunc1(): pass class email_logit(logit): def __init__(self, email="admin@myproject.com", *args, ** kwargs): self.email = email super(email_logit,self).__init__(*args,**kwargs) def notify(self): #发送一个email到self.mail print("send a email......") """ @email_logit将会和@logit产生同样的效果, 但是在打日志的基础上, 还会多 发送一封邮件给管理员。 """
myfunc1() 输出: myfunc1was called notified
@email_logit() def my_func(): pass my_func() 输出: my_funcwas called send a email......