Python decorators look similar to annotations in Java, although they are not the same as annotations, but are also capable of faceted programming.
To understand decorators in Python, you have to understand the concept of closures.
closure
Take a look at this explanation from Wikipedia:
In computer science, closures (English: Closure), also called Lexical closures or function closures, are functions that refer to free variables. The referenced free variable will exist with the function, even if it has left the environment in which it was created.
But –talk is cheap, show me the code:
Def print_msg(): MSG = "I'm closure" Closure = print_msg() # print I'm closure closure()Copy the code
MSG is a local variable that should not exist after print_msg is executed. But the nested function refers to the variable, enclosing the local variable within the nested function, thus forming a closure.
If you look at wikipedia’s explanation with this example, it becomes much clearer. A closure is a function that refers to its own variable. This function holds the execution context and can exist independently of its original scope. Let’s look at decorators in Python.
A decorator
A common decorator would look like this:
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print('call %s():' % func.__name__)
print('args = {}'.format(*args))
return func(*args, **kwargs)
return wrapperCopy the code
This defines a decorator that prints the method name and its parameters.
Call it:
@log
def test(p):
print(test.__name__ + " param: " + p)
test("I'm a param")Copy the code
Output:
call test():
args = I'm a param
test param: I'm a paramCopy the code
The use of @ syntax in decorators is somewhat confusing. In fact, a decorator is just a method, no different from the following call:
def test(p):
print(test.__name__ + " param: " + p)
wrapper = log(test)
wrapper("I'm a param")Copy the code
The @ syntax simply passes functions to decorator functions, and there’s nothing magical about it.
Of note is @functools.wraps(func), which is a decorator provided by Python. It copies the meta information of the original function into the func function inside the decorator. Function meta-information includes docString, name, argument list, and so on.
Try unwrapping @functools.wraps(func) and you’ll see that the output of test.name becomes wrapper.
Decorator with parameters
Decorators allow parameters to be passed in. A decorator with parameters will have three layers of functions, as follows:
import functools
def log_with_param(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print('call %s():' % func.__name__)
print('args = {}'.format(*args))
print('log_param = {}'.format(text))
return func(*args, **kwargs)
return wrapper
return decorator
@log_with_param("param")
def test_with_param(p):
print(test_with_param.__name__)Copy the code
The internal decorator function argument func is passed in. It’s not the same as the usual decoration.
In fact, the reason is the same, remove the @ syntax, restore the form of the function call at a glance:
Pass in the decorator parameters, Decorator = log_with_param("param") # passes the wrapper = decorator(test_with_param) # Calling the wrapper decorator function ("I'm a param") produces the same result as normal use of the decorator: call test_with_param(): args = I'm a param log_param = param test_with_paramCopy the code
At this point, the somewhat convoluted feature of decorators is no mystery.
The decorator syntax shows that functions are first citizens in Python. Functions are objects, variables, parameters, and return values.
Python introduces a lot of functional programming features that need to be learned and understood.
The original link: www.jianshu.com/p/ee82b9417… Wenyuan network, for learning purposes only, delete.
You will definitely encounter difficulties in learning Python. Don’t panic, I have a set of learning materials, including 40+ e-books, 800+ teaching videos, covering Python basics, crawlers, frameworks, data analysis, machine learning, etc. Shimo. Im/docs/JWCghr… Python Learning Materials
Follow the Python circle and get good articles delivered daily.