装饰器是一个很著名的设计模式,常常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。
装饰器其实就是一个工厂函数,它接受一个函数为参数,而后返回一个新函数,其闭包中包含了原函数html
一、简单装饰器:前端
def deco(func): def wrapper(): print "start" func() #调用函数 print "end" return wrapper @deco def myfun(): print "run" myfun()
因为装饰器函数返回的是原函数的闭包wrapper,实际上被装饰后的函数就是wrapper,其运行方式就和wrapper同样。至关于:
myfun=deco(myfun)python
二、装饰任意参数的函数:django
def deco(func): def warpper(*args,**kw): print "start" func(*args,**kw) print "end" return warpper @deco def myfun1(param1): print "run with param %s"%(param1) @deco def myfun2(param1,param2): print "run with param %s and %s"%(param1,param2) myfun1("something") myfun2("something","otherthing") # start # run with param something # end # start # run with param something and otherthing # end
三、带参数的装饰器设计模式
装饰器接受一个函数做为参数,这个毋庸置疑。可是有时候咱们须要装饰器接受另外的参数。此时须要再加一层函数,其实是定义了一个生成装饰器的工厂函数,调用它,搭配须要的参数,来返回合适的装饰器session
def log(text): def deco(func): def wrapper(*args,**kw): print text func(*args,**kw) print text + " again" return wrapper return deco @log("hello") def myfun(message): print message myfun("world") # hello # world # hello again
log=log("hello"),把返回的deco函数赋值给log,此时log至关于其包含text=“hello”的闭包
myfun=log(myfun),至关于把myfun传入了deco函数,而且返回wrapper,并赋值给myfun,此时myfun至关于其装饰后的闭包。
总体来看是myfun=log("hello")(myfun)闭包
四、装饰器带类参数app
class locker: def __init__(self): print("locker.__init__() should be not called.") @staticmethod def acquire(): print("locker.acquire() called.(这是静态方法)") @staticmethod def release(): print(" locker.release() called.(不须要对象实例)") def deco(cls): '''''cls 必须实现acquire和release静态方法''' def _deco(func): def __deco(): print("before %s called [%s]." % (func.__name__, cls)) cls.acquire() try: return func() finally: cls.release() return __deco return _deco @deco(locker) def myfunc(): print(" myfunc() called.") myfunc() myfunc()
五、django自定义装饰器实现登陆验证函数
def Check_Login(func): #自定义登陆验证装饰器 def warpper(request,*args,**kwargs): is_login = request.session.get('IS_LOGIN', False) if is_login: func(request,*args,**kwargs) else: return HttpResponseRedirect("/polls/login_user") return warpper def login_user(request): if request.method == 'POST': form = LoginForm(request.POST) if form.is_valid(): all_data = form.clean() #获取post数据,例如 {'username': u'yang1', 'password': 111} exist = User.objects.filter(username = all_data['Form_username'],password = all_data['Form_password']).first() if exist: request.session['IS_LOGIN'] = True #设置session的随机字段值 request.session['uname'] = exist.username #设置uname字段为登陆用户 return HttpResponseRedirect('/polls/home') else: return HttpResponse("帐户或密码错误") else: form = LoginForm() return render(request, 'polls/login_user.html', {'form': form}) @Check_Login def home(request): username = request.session.get('uname', False) #获取登陆用户名 return render(request, 'polls/home.html', {'username': username}) #用户名渲染到前端页面