1. iterators
Here, let's review what is an iterative object (iterable)?
An object that can directly act on a for loop is collectively known as an iterative object , that is, iterable.
# One is a collection of data types, such as list, tuple, dict, set, str, etc.;
The second is the generator, which includes the generator and the generator function with yield.
An object that can be called by the next () function and continually returns the next value (until the stopiteration error is thrown without data ) is called an iterator, or iterator.
The Python iterator (iterators) object needs to support the following two methods when adhering to the iterator protocol.
__ITER__ () Returns the Iterator object itself. This is used in the for and in statements.
__NEXT__ () returns the next value of the iterator. If no next value can be returned, then the stopiteration exception should be thrown.
#!/usr/bin/python#Coding=utf-8classCount (object):def __init__(Self,low,high): Self.low=Low Self.high= Highdef __iter__(self):return Selfdef __next__(self):ifSelf.low >Self.high:RaisestopiterationElse: Self.low= Self.low + 1returnSelf.low-1
>>> fromTestImportCount>>> C = Count (5,10)>>>C<test. Count Object at 0x7f84b94abe10>>>> forIinchC: ...Print(I,end =' ')... 5 6 7 8 9 >>> >>> C.__next__<bound method Count.__next__of <test. Count Object at 0x7f84b94abe10>>>>>Next (C) Traceback (most recent): File"<stdin>", Line 1,inch<module>File"/home/test/python/test.py", Line 13,inch __next__ Raisestopiterationstopiteration>>> C = Count (5,6)>>>Next (C)5>>>Next (C)6>>>Next (C) Traceback (most recent): File"<stdin>", Line 1,inch<module>File"/home/test/python/test.py", Line 13,inch __next__ Raisestopiterationstopiteration
2. Generator
What we always say 生成器,
is the function that comes with it yield
.
def counter_generator (Low, High ): ... while low <= high : ... yield Low ... + = 1 for in Counter_generator (5,10): ... Print (I, end='5 6 7 8 9 10
In a while loop, each time a yield statement is executed, the value of the variable low is returned and the generator state transitions to pending. The next time the generator is called, the generator resumes execution from where it was previously frozen and the value of the variable low is increased by one. The generator continues the while loop and comes back to the yield statement ...
When you call the generator function, it returns a generator object. If you pass this object to the Dir () function, you will find the __iter__ and __next__ two method names in the returned results.
We typically use generators for lazy evaluation. Using generators in this way is a good way to handle big data. If you don't want to load all the data in memory, you can use the generator to pass only a subset of your data at a time.
The Os.path.walk () function is the most typical example of this, which uses a callback function and the current Os.walk generator. Save memory with the builder implementation.
We can use generators to produce an infinite number of values. Here is an example of this.
def infinite_generator (start=0): ... while True: ... yield start ... + = 1 ... for in Infinite_generator (4): ... Print (Num, end=" ) ... if num >: ... Break ... 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
The generator must not repeat the loop.
3. Closures
A closure (Closures) is a function returned by another function. We use closures to remove duplicate code. In the following example, we create a simple closed package to sum the numbers
def add_number (num): ... def Adder (number): ... # Adder is a closed package ... return num + number ... return Adder ... >>> a_10 = Add_number (ten)>>> a_10 (+)31>>> a_10 (44) >>> a_5 = add_number (5)>>> a_5 (3)8
Adder is a closure that adds a given number to a predefined number.
4. Decorative Device
Adorners (decorators) are used to dynamically add some new behaviors to some objects, and so are the closures we used.
An adorner is actually a closure, taking a function as a parameter and returning an alternative function
>>>defMy_decorator (func): ...defWrapper (*args, * *Kwargs): ...Print("before call") ... result= Func (*args, * *Kwargs) ...Print(" after call")... returnresult ...returnwrapper ...>>>@my_decorator ...defAdd (A, B): ...#our summation function....returnA +b .....>>> Add (1, 3) before Callafter call4
When you define a function, you use *, which means that parameters passed by location are placed in a variable with a * prefix, so:
defOne (*args):PrintArgs#1One () () One (1, 2, 3)(1, 2, 3)defBoth (x, Y, *args):#2 Printx, Y, Argstwo ('a','b','C') a B ('C',)
The first function one simply says that any pass-through positional parameters are all printed out, and you can see that in code # # We just refer to the variable args within the function, and *args just used the function definition to indicate that positional parameters should be stored in the variable args. Python allows us to set some parameters and capture all the remaining non-captured positional parameters through args, as shown in Listing #.
The * operator can also be used when a function is called. The meaning is basically the same. When a function is called, a variable with a * flag means that the contents of the variable need to be extracted and used as positional parameters. Similarly, let's look at an example:
def Add (x, y): return x += []add (lst[0], lst[# 13Add (# 2 3
The code at the #1处的代码和 # # is actually the same thing, and what Python does for us can actually be done manually. This is not a bad thing,*args either means that when the calling method is large, additional parameters can be obtained from an iterative list, or the method is defined to accept arbitrary positional parameters.
The next mention of the * * will be slightly more complex, * * represents the key-value pairs of the dining-house dictionary, and * The meaning of the same, is very simple right:
def Foo (* *Kwargs) :print kwargsfoo () {}foo (x=1, y=2) {' y ' ' x ': 1}
When we define a function, we can use **kwargs to indicate that all the non-captured keyword parameters should be stored in the Kwargs dictionary. As previously mentioned, Argshe Kwargs is not part of the Python syntax, but when defining a function, using such variable names is an unwritten convention. As with *, we can also use * * when defining or invoking a function.
DCT = {'x'y': 2}def Bar (x, y): return x + Ybar (* *DCT)3
A more versatile decorator
def Logger (func): def inner (*args, **kwargs): # 1 print " arguments were:%s,%s " % (args, Kwargs) return func (*args, **kwargs) # Span style= "COLOR: #008000" >2 return inner
def foo1 (x, Y=1): return x *def Foo2 (): return 2foo1 (5, 4) Arguments were: (5, 4), {}foo1 (1) Arguments were: ( 1,), {}1foo2 () Arguments were: (), {}2
Notice our function inner, which can accept any number and type of arguments and pass them to the wrapped method, which allows us to decorate any method with this adorner.
http://python.jobbole.com/81683/
iterators, generators, adorners