Catalog
1 Decorator
1.1 Purpose, application scenario:
-
Purpose:
Without changing the internal code of the original function, the function is customized before and after execution.
-
Application scenarios:
When you want to extend functions, you can choose to use decorators.
1.2 Writing Decorators and Applications
-
Basic Decorator
# Decorator Format (Double Nested Functions) def outer layer function (parameter): def inner function (* arg,**kwarg) return parameter (* arg,**kwarg) return inner function # Application Format of Decorator @ Outer Layer Function The function to be decorated by def () pass # Execution function, automatic trigger decorator Functions to decorate ()
Exercises
def func(arg): def inner(): print('before') v = arg() print('after') return v return inner def index(): print('123') return '666' # Example 1 v1 = index() # Execute the index function, print 123 and return 666 to assign to v1. # Example 2 v2 = func(index) # v2 is inner function, arg=index function index = 666 v3 = v2() # Example 3 v4 = func(index) index = v4 # index ==> inner index() # Example 4 index = func(index) index()
def func(arg): def inner(): v = arg() return v return inner # Step 1: Execute the func function and pass the following function parameters, equivalent to: func(index) # Step 2: Reassign the return value of func to the following function name. index = func(index) @func def index(): print(123) return 666 print(index)
# Calculate function execution time def wrapper(func): def inner(): start_time = time.time() v = func() end_time = time.time() print(end_time-start_time) return v return inner @wrapper def func1(): time.sleep(2) print(123) @wrapper def func2(): time.sleep(1) print(123) def func3(): time.sleep(1.5) print(123) func1()
Note: Question: Why add * arg,** kwarg
Understand:
-
-
Variable assignment
```python
def func():
print(1)v1 = func
func = 666
```Look at what exactly is return ed?
I have to find my own, I did not go to the scope of the higher level to find.
Reception:
python @xx # index = xx(index) def index(): pass index()
-
On parameters
def x(func): def inner(a1): return func(a1) return inner @x def index(a1): pass
def x(func): def inner(a1,a2): return func(a1,a2) return inner @x def index(a1,a2): pass # index = inner index(1,2) # ################################### The purpose of parameter unification is to transfer parameters to the original index function. def x(func): def inner(a1,a2): return func() return inner @x def index(): pass # func = original index function u # index = inner index(1,2)
What if you write a unified decorator for several functions?
def x1(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner @x1 def f1(): pass @x1 def f2(a1): pass @x1 def f3(a1,a2): pass
Decorator Suggested Writing:
def x1(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return data return inner
-
-
Decorator with parameters
# Step 1: Execute v1 = uuu(9) # Step 2: ret = v1(index) # Step 3: index = ret @uuu(9) def index(): pass
# ################## Ordinary ornaments ##################### def wrapper(func): def inner(*args,**kwargs): print('Before calling the original function') data = func(*args,**kwargs) # Execute the original function and get the return value print('After the caller function') return data return inner @wrapper def index(): pass # ################## Decorator with parameters ##################### def x(counter): def wrapper(func): def inner(*args,**kwargs): data = func(*args,**kwargs) # Execute the original function and get the return value return data return inner return wrapper @x(9) def index(): pass
Exercises
# Write a decorator with parameters, realize: how many parameters, how many times will the decorated function be executed, add each result to the list, and finally return to the list. def xxx(counter): print('x function') def wrapper(func): print('wrapper function') def inner(*args,**kwargs): v = [] for i in range(counter): data = func(*args,**kwargs) # Execute the original function and get the return value v.append(data) return v return inner return wrapper @xxx(5) def index(): return 8 v = index() print(v) # Write a decorator with parameters to achieve: how many parameters, how many times the decorated function will be executed, and return the results of the last execution. def xxx(counter): print('x function') def wrapper(func): print('wrapper function') def inner(*args,**kwargs): for i in range(counter): data = func(*args,**kwargs) # Execute the original function and get the return value return data return inner return wrapper @xxx(5) def index(): return 8 v = index() print(v) # Write a decorator with parameters to achieve: how many parameters, how many times the decorated function will be executed, and return the maximum value of the execution results. def xxx(counter): print('x function') def wrapper(func): print('wrapper function') def inner(*args,**kwargs): value = 0 for i in range(counter): data = func(*args,**kwargs) # Execute the original function and get the return value if data > value: value = data return value return inner return wrapper @xxx(5) def index(): return 8 v = index() print(v)
def x(counter): print('x function') def wrapper(func): print('wrapper function') def inner(*args,**kwargs): if counter: return 123 return func(*args,**kwargs) return inner return wrapper @x(True) def fun990(): pass @x(False) def func10(): pass
-
2 iterator
I can't write iterators myself, just use them.
Task: Please show all the data in the list.
while + Index + Counter
-
Iterator, one by one acquisition of elements in an object (an object created by the str/list/tuple/dict/set class) - an iterative object
Representation: Has _ next _ method and obtains elements in the iteratable object (one before and one after each call).
-
First convert an object (such as a list) into an iterator
v1 = iter([11,22,33,44])
v1 = [11,22,33,44]_ _ iter _ ()
-
The iterator wants to get each value: repeated calls (val = v1. next ())
v1 = [11,22,33,44] # List conversion to iterator v2 = iter(v1) result1 = v2.__next__() print(result1) result2 = v2.__next__() print(result2) result3 = v2.__next__() print(result3) result4 = v2.__next__() print(result4) result5 = v2.__next__() # v1 has only four elements, and the fifth acquisition will result in an error: StopIteration print(result5) v1 = "alex" v2 = iter(v1) while True: try: val = v2.__next__() print(val) except Exception as e: break
-
Until an error is reported: StopIteration error indicates that the iteration has been completed.
How to judge whether an object is an iterative object: whether there are _ next _ methods in it.
-
-
for loop:
v1 = [11,22,33,44] # 1. Internally converts v1 into an iterator # 2. Internal repetitive iterator. _next_() # 3. Make no mistake after taking for item in v1: print(item)
3 Iterable Objects
-
Internally has iter () method and returns an iterator
v1 = [11,22,33,44] result = v1.__iter__()
Can be cycled for
-