One, decorator
1, Concept
Decorator is to add new functions to existing modules, such as login verification function, run time function, etc. itself can be any callable object, or the adorner can be any callable object.
The principle of emphasizing adorners: 1 do not modify the source code of the Decorated object 2 does not modify the method of calling the decorated object
Object of the adorner: Add new features to the adorned object, following the 1 and 2 prerequisites
2, Theoretical basis
To realize the function of adorners, we need three theoretical bases: function closure + function nesting + higher order function. We explain how to use it by adding an adorner for the following module to the statistics run time
Import Time def Test_func (): for in range (5): time.sleep (0.5)
3, derivation
First we know that to know the running time of the function, we just need to add the current time before and after the function, which can be calculated by the difference value. So we can define a module and pass in the function address of the function we are seeking, that is, the higher order function.
The function that contains the call and statistic time of this function in the module
import time def Test_func (): for i in range (5 ): Time.sleep ( 0.5 def Decorate (func): start_time = Time.time () func () end_time = Time.time () print (End_time-start_time) Decorate (test_func) # 2.5s
This realizes the function of the statistic time, but modifies the function's invocation logic, so we can define the function within the adorner function and call the statistical function within the function, that is, the function is nested, and returns
The code is as follows:
import time def Test_func (): for i in range (5 ): Time.sleep ( 0.5 def Decorate (func): def Span style= "COLOR: #000000" > Count_time (): start_time = Time.time () func () end_time = Time.time () print (End_time-start_time) return Count_timetest_func = decorate (test_func) Test_func ()
And Python provides us with the adorner syntax:
Import Time def Decorate (func): def count_time (): = Time.time () func () end_time=time.time () print(end_time- start_time) returndef Test_func (): for in range (5): time.sleep (0.5) test_func ()
The above implements a simple adorner, which can increase its function according to the requirement, such as incoming parameter, return value, etc.
Second, iterators
1, Concept
An iterator (Iteretor) is a way to traverse all or part of a container, a complex pointer that traverses a complex data structure, and a container should provide its own iterator.
2, iterator object and iterator object
Iterator object: That is, the object can provide a way to traverse it, like a concrete representation of an iterator, in Python the iterator object can provide the __iter__ and __next__ methods to get the value of the next element in the container.
An iterative object: That is, the object provides a __iter__ method that uses the method to get an iterator object, such as a string, a list tuple
li=[1,2,3,4,5]li=li.__iter__() # can iterate objects into iterator objects print(li.__next__ () # 1
3, how to use
DIC = {"a": 1,"e": 4,"b": 2,"C": 3,"D": 4}iter_dic= dic.__iter__()#While True:Try: Print(Next (Iter_dic))#"A" "E" "B" .....exceptStopiteration:#need to catch exceptions manually Break
And we can iterate through the container with a powerful for loop mechanism in Python.
4,for Cycle
#based on the for loop, we can completely no longer rely on the index to fetch the value.DIC = {'a': 1,'b': 2,'C': 3} forKinchDIC:Print(Dic[k])#how the For loop works#1: The dic.__iter__ () method that executes the in object, the iterator object. __iter, returns the object itself. Get an Iterator object Iter_dic#2: Perform next (iter_dic), assign the resulting value to K, and then execute the Loop body code#3: Repeat the process 2 until the exception stopiteration is caught, ending the loop
Third, generator
Python uses generators to implement deferred operations, which are deferred operations that produce results when they are needed, and do not occur when they are not needed. There are two ways to provide a builder object:
1, generator function : Just like a regular function definition, instead of return, use yield to return the result. Returns only one result at a time, in the middle of each result, suspends the function state so that the next time it continues to return.
2, Generator expression : Generates a Generator object, produces the result on demand, or produces a specific value when iterating.
1, generator function
def Gensquares (n): for i in range (n): Span style= "COLOR: #0000ff" >yield i * * 2obj = gensquares (5" print (obj) # Span style= "COLOR: #008000" > <generator object gensquares at 0x00000000021e55c8> print (Next (obj)) # 0 print (Next (obj)) # 1 print (Next (obj)) # 4
2, Generator expression
Li = [] forIinchRange (5): Name="name%d"%I li.append (name)Print(LI)#[' NAME0 ', ' name1 ', ' name2 ', ' name3 ', ' name4 ']#List DerivationLi = ["name%d"% i forIinchRange (5)]Print(LI)#[' NAME0 ', ' name1 ', ' name2 ', ' name3 ', ' name4 ']#a lot of brevity.#Builder ExpressionGens = ("name%d"% i forIinchRange (5))Print(gens)#<generator Object <genexpr> at 0x00000000028655c8>Print(Next (gens))#NAME0Print(Next (gens))#name1Print(Next (gens))#Name2
#生成器对象就是迭代器对象
The benefits of using the generator data are not loaded directly into memory, and are very useful in situations where the amount of data is large. For example, use built-in functions like
# Print (sum ([I for I in Range (100000000)]) #提示计算机内存不足, program crashes Print for inch # normal operation of the process
Note: The Builder object is an iterator object that can traverse only once, and iterate over an object multiple times.
The second chapter of Python-Decorators and iterators, generators