First of all, recalling the comments onPython Decorators and Decorator Patterns
make up a deficiency
According to the Java implementation of the decorator pattern, we can write the following piece of code:
import logging def use_logging(func): ("%s is running" % func.__name__) return func def foo(): print('i am foo') foo = use_logging(foo) foo() # call (programming)
This implementation uses decorators for Java as mentioned in the previous post. The above is also a decorator to implement the simplest one to increase the function logging, but if this additional function is to go to detect the incoming parameters, then the above will not work. At this point the example in 12 Easy Steps to Python Decorators is still subtle.
# Decorator def wrapper(func): def checker(a, b): # 1 if < 0 or < 0: a = Coordinate( if > 0 else 0, if > 0 else 0) if < 0 or < 0: b = Coordinate( if > 0 else 0, if > 0 else 0) ret = func(a, b) if < 0 or < 0: ret = Coordinate( if > 0 else 0, if > 0 else 0) return ret return checker # Original function def add(a, b): return Coordinate( + , + ) # Use of decorations add = wrapper(add)
Carefully you will find that the parameters of the decorator function is the original function passed in, and the parameters of the internal function is exactly the same as the original function, the outermost return is a reference to the internal function, the internal function returns a reference to the incoming parameters of the result of the call
The function-as-argument feature is used here, and of course there's some closure knowledge, see the link to the blog mentioned above, it's really good.
The Python decoration feature mentioned in the last post is this amazing syntactic sugar, which can be used like this
# Original function @wrapper def add(a, b): return Coordinate( + , + )
Decorator with parameters
If one were to implement a decorator with parameters, how would one write the
def time_diff(s): def decorator(func): def wrapper(*args, **kwargs): start_time = () res = func(*args, **kwargs) end_time = () print("[%s] Time taken to execute program: %s" % (s, end_time - start_time)) return res return wrapper return decorator @time_diff("polynomial_1") def polynomial_1(n, x): res = 0 for i in range(n): res += i*pow(x, i) return res
Call and execute the output:
print(polynomial_1(1, 5)) [duoxiangshi_1]Time taken to execute the program: 4.76837158203125e-06 0
Decorators with parameters require another layer of functions to be defined outside of the decorator without parameters, and the return value of the outermost function is a reference to the second layer of functions.
In summary: more practice, used in practice, in order to be more skillful. Recently, I've been studying data structures and algorithms, and it's really convenient to write some decorators to see the execution time of the program!