First of all to analyze the requirements, the Web application background needs authentication, the background page contains multiple pages, the most common method is to add authentication for each URL, but this requires each binding URL of the background functions need to add similar or the same code, but the code is too redundant, and is not conducive to expansion.
Next we don't talk about adorners, we all know that Python is a very powerful language, she can pass functions as arguments to functions, the simplest:
Def p (): print ' Hello,world ' def funcfactor (func): print ' calling function named ', func.__name__ func () print ' End ' Funcfactor (p) # output is: # calling function named p# hello,world# end
At a glance, the program defines a function p (), passes the function p as a parameter to shout out the funcfactor, and adds some action before and after executing the P function.
We can also do this:
Def p (): print ' Hello,world ' def funcfactor (func): print ' calling function named ', func.__name__ return Funcfunc = Funcfactor (P) func () # output is: # calling function named Phello,world
As you can see, we could return the function and assign it to a variable to be called later. But in this case we're not going to be able to do something after the function is executed, but our Python is powerful, python can nest a function in a function, and we can do it like this:
Def p (): print ' Hello, World ' Def Funcfactor (func): def wrapper (): print ' does something at start ' func () C4/>print ' Do something at end ' return wrapperfunc = Funcfactor (P) func () #输出为: # does something at start# Hello, world# do Something at end
Here we look at the adorner, the above code although the implementation of a very difficult task, but is not elegant, and the code does not conform to the philosophy of Python, so the adorner came out, the adorner is not the same principle as above, the same for the wrapper function, Just the code implementation is more elegant and easy to read. The adorner follows the name of the adorner at the beginning of the @, and the next line is the function body to be wrapped, and the example above is implemented in the following way:
def decorator (func): def wrapper (): print ' Do something at start ' func () print ' Do something at end '
return wrapper@decoratordef P (): print ' Hello, World ' P () #输出为: # does something at start# Hello, world# does something at End
In fact, the adorner does not have performance or other aspects of Ascension, is only a syntactic sugar, is the above example of rewriting, so more elegant and reading. If our P () function doesn't want to just lose hello,world, we want to say hello to some of our designated people:
def decorator (func): def wrapper (*args, **kargs): print ' Do something at start ' func (**kargs) print ' Do something at end ' return wrapper@decoratordef P (name): print ' Hello ', NAMEP (name= "Jim") #输出为: # does something at start# Hello jim# do something at end
Adorners are not required to decorate an adorner nesting function that does not require parameters, and if the decorated function requires parameters, a function must be nested to handle the parameters. It is written here that everyone knows the use and function of adorners. Now back to the point, how elegant to the background URL plus verification function? No doubt we use adorners to handle:
def Blog_auth (func): " defines an adorner to be used to decorate a page adorner that needs to be validated must be placed under the route adorner " ' # defines the wrapper function def wrapper ( *args, **kargs): try: # Read Cookie user = Request. cookies[' user '] shell = Request. cookies[' shell '] except: # exception is redirected to login page redirect ('/login ') # Verify user Data if Checkshell (user, Shell): # Verify success returns function return func (**kargs) else: # Otherwise redirect to login page redirect ('/login ') Return wrapper
You can add Blog_auth adorners where you need to verify again:
@route ('/admin:#/?# ') @blog_authdef admin (): " for Display admin home page ' template[' title '] = ' Dashboard | ' + template[' blog_name '] template[' user ' = Request. cookies[' user '] articles = [] for article in Db.posts.find (). Sort ("date", descending). Limit (Ten): Articles.append (article) # give the list of articles to the foreground template template[' articles '] = articles return TEMPLATE (' admin.html ', TEMPLATE)
At this point, the problem of bottle verification is elegantly solved with the decorator.