Python裝飾器、Django自定義登錄驗證


裝飾器是一個很著名的設計模式,經常被用於有切面需求的場景,較為經典的有插入日志、性能測試、事務處理等。
裝飾器其實就是一個工廠函數,它接受一個函數為參數,然后返回一個新函數,其閉包中包含了原函數

1、簡單裝飾器:

def deco(func):
    def wrapper():
        print "start"
        func() #調用函數
        print "end"
    return wrapper

@deco
def myfun():
    print "run"

myfun()

由於裝飾器函數返回的是原函數的閉包wrapper,實際上被裝飾后的函數就是wrapper,其運行方式就和wrapper一樣。相當於:
myfun=deco(myfun)

2、裝飾任意參數的函數:

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

 3、帶參數的裝飾器

裝飾器接受一個函數作為參數,這個毋庸置疑。但是有時候我們需要裝飾器接受另外的參數。此時需要再加一層函數,實際上是定義了一個生成裝飾器的工廠函數,調用它,搭配需要的參數,來返回合適的裝飾器

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)

4、裝飾器帶類參數

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()

 5、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}) #用戶名渲染到前端頁面

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM