python iterator and generator, decorator

Posted by Gath on Thu, 10 Feb 2022 21:35:21 +0100

python iterator and generator, decorator

The iterator object is accessed from the first element of the collection until all the elements are accessed.
Iterators have two basic methods: iter() and next().
String, list, or tuple objects can be used to create iterators:

list1=[1,2,3]
s=iter(list1) # Create iterator object
print(next(s)) # The next element of the output iterator
print(next(s))
print(next(s))


Until the last element is calculated and there are no more elements, the StopIteration error is thrown

Iterator objects can be traversed using regular for statements:

list2=[1,2,3,4,5]
s2 = iter(list2)    # Create iterator object
for h in s2:
    print (h, end="-")


generator
Functions with yield are called generator s in Python
(making your own iterator can be regarded as a generator)

#Notice the parentheses
#List generation
lis = [x+x for x in range(5)]
print(lis)
#generator 
gen= (x+x for x in range(5))
print(gen)
# gen = (x+x for x in range(5))
# print(next(gen))
# print(next(gen))
# print(next(gen))
# print(next(gen))
# print(next(gen))
generator_ex = (x+x for x in range(5))
for i in generator_ex:
    print(i)


Generate a range generator that supports decimals (i.e. iterator with yield)

You first think of yield as "return". This is intuitive. It is first a return. What does ordinary return mean? It means to return a value in the program. After returning, the program will not run down. See it as a return and then as part of a generator (a function with yield is a real iterator),
https://blog.csdn.net/mieleizhi0522/article/details/82142856

def frange(star,stop,step):
    x=star
    while x<stop:
        yield x
        x+=step
for i in frange(10,20,0.5):
    print(i)


The following figure shows the function of yield most intuitively

Think of yield as return. After returning a 4, the program stops and does not perform the operation assigned to res.
A function with yield is a generator. Generating a generator looks like a function call, but it will not execute any function code until it calls next() (next() will be called automatically in the for loop). When the yield statement is executed, it will continue to execute the next iteration from the yield statement. It looks like a function is interrupted several times by yield during normal execution, and each interrupt will return the current iteration value through yield. https://www.runoob.com/w3cnote/python-yield-used-analysis.html

def foo():
    print("starting...")
    while True:
        print("yield front")
        res = yield 4
        print("yield after")
        print("res:", res)


g = foo()
print(next(g))
print("*" * 20)
print(next(g))


Decorator https://www.cnblogs.com/ellisonzhang/p/11196390.html

When we call this function, the first thing is not to execute this function, but to pass this function as a parameter into the hat on its head, which we call a decorator function or decorator.
The use method of the decorator is very fixed:
First define a decoration function (HAT) (it can also be implemented with classes and partial functions)
Define your business function or class (person)
Finally, put this hat on this head
There are many simple uses of decorators. Here are two common ones.
Log printer
Watch Timer

# This is the decoration function
def logger(func):
    def wrapper(*args, **kw):
        print('I'm going to start the calculation:{} Function:'.format(func.__name__))

        # The real implementation is this line.
        func(*args, **kw)

        print('Aha, I've finished the calculation. Add yourself a chicken leg!!')
    return wrapper

@logger
def add(x, y):
    print('{} + {} = {}'.format(x, y, x+y))
add(200, 50)

# This is the decoration function
def timer(func):
    def wrapper(*args, **kw):
        t1=time.time()
        # This is where the function actually executes
        func(*args, **kw)
        t2=time.time()

        # Calculate the down time
        cost_time = t2-t1
        print("Time spent:{}second".format(cost_time))
    return wrapper

import time

@timer
def want_sleep(sleep_time):
    time.sleep(sleep_time)

want_sleep(10)

def american():
    print("I come from China.")


def chinese():
    print("I am from America.")


def say_hello(contry):
    def wrapper(func):
        def deco(*args, **kwargs):
            if contry == "china":
                print("Hello!")
            elif contry == "america":
                print('hello.')
            else:
                return

            # Where the function is actually executed
            func(*args, **kwargs)

        return deco

    return wrapper


@say_hello("china")
def american():
    print("I come from China.")


@say_hello("america")
def chinese():
    print("I am from America.")


Decorator example source: https://www.cnblogs.com/ellisonzhang/p/11196390.html

Topics: Python