This is the 18th day of my participation in the August Genwen Challenge.More challenges in August

📖 preface

Sanmao once sighed:

“What is the mind like? There is a labyrinth that stretches thousands of miles across. There is no boat that can ferry people. Throughout life, we are learning how to be our own ferrymen.

You can watch this blogger’s article about installation and LocalizationVsCode download, Installation and LocalizationAs well asPython series: windows10 configuration Python3.0 development environment!After installation, restart VsCode!


🚀 last Come on! What is recursion:

Inside a function, you can call other functions. A function is recursive if it calls itself internally. Remember -> Calling other functions inside a function is not nesting, but defining child functions inside a function is nesting.

  • Recursive features:
  1. Recursive functions must have an explicit termination condition.

  2. With each further recursion, the problem size should decrease relative to the last recursion

  3. There is a close connection between two adjacent repetitions, and the previous one prepares for the next one (usually the output of the previous one serves as the input of the next one).

  4. Recursion is not efficient, and too many levels of recursion will lead to stack overflow (in computers, function calls are implemented by the data structure stack (stack), each time a function call is entered, the stack will add a layer of stack frame, each time the function returns, the stack will subtract a layer of stack frame. Because the stack size is not infinite, too many recursive calls can cause stack overflow.

Take the following example

"@descripttion: This is a header comment! @version: 1.0.0 @company: dcit-sh @author: Sunny Chen @Date: 2019-10-09 18:20:20 @lasteditors: Sunny Chen @LastEditTime: 2019-10-15 09:58:20 '''

import sys
# Add through a loop
def sum1(n) :
    ''' to n,The sum function '''
    sum = 0
    for i in range(1,n + 1) :sum += i
    return sum

# Add by recursion of functions
def sum2(n) :
    ''' to n,The sum function '''
    if n > 0:
        return n + sum2(n - 1) Call the function itself
    else:
        return 0

print("Loop overlay" -->,sum1(50))
print("Recursive stacking" -->,sum2(50))

# 1275 = 1275
Copy the code

Both can be superimposed. What are the advantages and disadvantages of the latter versus the former?


✨ What are the advantages and disadvantages of recursive functions?

Advantages of recursive functions: simple definition and clear logic. Theoretically, all recursive functions can be written as loops, but the logic of loops is not as clear as recursion.

Disadvantages of recursive functions: Using recursive functions requires care to prevent stack overflow. In computers, function calls are implemented by a data structure called the stack. Each time a function call is entered, a stack frame is added to the stack, and each time the function returns, a stack frame is subtracted. Because the stack size is not infinite, too many recursive calls can cause stack overflow.

Changing the above recursive summation function to 10000 will cause stack overflow!

Of course, recursive stack overflow can also be optimized by tail recursion. I won’t go into the details here. See (Tail Recursion optimization enabled in Python!) :www.open-open.com/lib/view/op…


🤳 introduces function recursion by example:

"@descripttion: This is a header comment! @version: 1.0.0 @company: dcit-sh @author: Sunny Chen @Date: 2019-10-09 18:20:20 @lasteditors: Sunny Chen @LastEditTime: 2019-10-15 10:20:37 '''

# If there are such a group of people on the street, I would like to know where the snack street in Changsha is. Only two of them know where it is.
names = ["Little Jia Jia"."Liu."."Zhang"."Bill"."Two Dogs"."Fifty"]
print(names)
# the way

def ask_way(lis) :
    # Alone on the street
    if len(lis) == 1:
        return "No one knows where this place is."
    # If I'm not alone on the street, ask the first person
    name = lis.pop(0)
    # If the person is two dogs, then ask for directions, the recursion ends
    if name == "Two Dogs":
        return "Two dog son say: changsha snack street in tianxin district south gate!!"
    # If the person does not know the way, ask the next person so that the next person can tell the result.
    print("<%s> Ask: you [%s] good, excuse me, do you know where changsha snack street is?" % (name, lis[0]))
    print("Sorry, I will ask %s for you, he may know!! \n" % lis[0])
    res = ask_way(lis)
    ifname ! ="Little Jia Jia":
        print("Said > < % s: % s" % (name, res))
    return res

ask_way(names)

The output is as follows:
"" "[' little jia jia ', 'liu 2', 'zhang', 'bill', 'dog 2', 'Cathy'] < small jia jia > q: [2] liu you ok, do you know where is the snack street in changsha? Sorry, I will ask Liu er for you, he may know!! < liu er > ASK: you [Zhang SAN] good, excuse me, do you know where changsha snack street is? Sorry, I will ask Zhang SAN for you, he may know! < Zhang SAN > Q: you [Li Si] good, excuse me, do you know where changsha snack street is? Sorry, I will ask Li Si for you, he may know! < li si > ask: you [erdogzi] good, excuse me, do you know where changsha snack street is? Sorry, I help you ask two dog son, he may know!! < li si > say: two dog son say: changsha snack street in tianxin district south gate!! < zhang SAN > say: two dog son say: changsha snack street in tianxin district south gate!! < liu 2 > say: two dog son say: changsha snack street in tianxin district south gate!! "" "
Copy the code

When the recursive value returns, it goes back to the previous layer, while the other layers wait for the answer as they execute. Go and try it!


🎇 last Come on! What is a decorator? :

Decorators: The first thing we need to know is that a Decorator is a function, and that the purpose of this function is to add additional functionality to other functions.

And to some extent, a decorator is not a feature, it is just a syntactic sugar, because in essence: it is to a function or object is passed as a parameter to a function or other object, and then returns the new function object, and this new function, or object inside already realized the function of the function, also for the additional new function.

In order to achieve the purpose of adding additional functions to other functions, two principles should be followed in this premise:

  • Do not modify the source code of the modified function.
  • 2. Do not modify the way the modified function is called.

The syntax is:

Decorator starts with “@”, and decorates additional functions for the function by adding “@xxx” on the line above the defined function. XXX is the decorator function name. Such as:

"@descripttion: This is a header comment! @version: 1.0.0 @company: dcit-sh@author: Sunny Chen @date: 2019-10-15 13:42:21 @lasteditors: Sunny Chen @LastEditTime: 2019-10-16 15:46:50 '''

# Decorator deco
def deco1(func) :
    pass
def deco2(func) :
    pass    

@deco1  The function name of the decorator, written on the line above the function to be decorated
@deco2  A function can have more than one decorator
The function to be modified is test
def test() :
    pass
Copy the code

🎊 last Come on! Why use decorators?

What decorators do :(each run separately)

"@descripttion: This is a header comment! @version: 1.0.0 @company: dcit-sh@author: Sunny Chen @date: 2019-10-15 13:42:21 @lasteditors: Sunny Chen @LastEditTime: 2019-10-16 15:48:59 '''
# Suppose your boss gave you a piece of code like this and asked you to calculate how long it would run.

import time
def test() :
    time.sleep(1)
    print("hello world")

#1 of course, the most direct way is to tamper with the source code, for example:
import time
def tests() :
    start_time =time.time()
    time.sleep(1)
    print("hello world")
    end_time =time.time()
    print("costed time-->%s",%(end_time-start_time))

#2, then the boss said: "This is the core code of our company, we can not modify the original code", then you may think of higher-order function to implement, the original function as a parameter to another function to implement:
import time
def test() :
    time.sleep(1)
    print("hello world")

def deco(func) :
    start_time =time.time()
    func()
    end_time = time.time()
    print("costed time-->%s"%(end_time-start_time)
# call
deco(test)


#3 when you present this code to your boss, your boss says: "This code is already in use, how can you change the call method?" And that's when you get annoyed, and that's when you think of higher-order functions as a return value
import time
def test() :
    time.sleep(1)
    print("hello world")

def deco(func) :
    start_time =time.time()
    func()
    end_time = time.time()
    print("costed time-->%s"%(end_time-start_time)
    return func
# call
test=deco(test)
test()


#4, you will find that the original function is executed twice, when the boss is not satisfied with it, "Oh my God, how can the original function be executed twice", so he asks you to change it again, when you see Lao Wang writing decoration next door, you will be surprised, so you have the following code:
import time
def test() :
    time.sleep(1)
    print("hello world")

def deco(func) :
    def wrapper(func) :
        start_time =time.time()
        func()
        end_time =time.time()
        print("costed time-->%s"%(end_time-start_time)
    return wrapper

test = deco(test)
test()


Deco is the original slave state of the decorator. This is what happens with decorators.
import time
# Decorator deco
def deco(func) :
    def wrapper(func) :
        start_time =time.time()
        func()
        end_time =time.time()
        print("costed time-->%s"%(end_time-start_time)
    return wrapper
# the function being decorated
@deco  #@deco <==> test =deco(test)
def test() :
    time.sleep(1)
    print("hello world")
# call
deco()
Copy the code

As you can see from the above example, you can use a decorator to add new additional functionality to a function without modifying the source code of the function being decorated or changing how the function is called.


💕 last Come on! How to implement decorators?

Before we can implement decorators, we need to understand higher-order functions, nesting of functions, and closures. Of course, I will cover these in other articles.

Decorated functions that take arguments and how decorated functions that return values implement decorators.

Code split 1-3(run separately)

"@descripttion: This is a header comment! @version: 1.0.0 @company: dcit-sh@author: Sunny Chen @date: 2019-10-15 13:42:21 @lasteditors: Sunny Chen @LastEditTime: 2019-10-16 15:54:58 '''

#1. Basic implementation of decorator
import time
def timmer(func) :
    def warpper() : An intermediate function needed to avoid the function being run twice
        start_time= time.time()
        func()
        end_time =time.time()
        print("cost time--->:",end_time-start_time)
    return warpper

@timmer #@timmer <--> test=timmer(test)
def test() :
    time.sleep(1)
    print("in the test.")

test() Test =timmer(test); If you call test, you're essentially calling warpper, the subfunction of timmer.

#2, if the function being decorated has a return value
import time
def timmer(func) :
    def warpper() : An intermediate function needed to avoid the function being run twice
        start_time= time.time()
        res=func()
        end_time =time.time()
        print("cost time--->:",end_time-start_time)
        return res
    return warpper

@timmer #@timmer <--> test=timmer(test)
def test() :
    time.sleep(1)
    print("in the test.")
    return "This is test' result"

test() The wrapper() return value of test() is the wrapper() return value. The function to be decorated needs to be a return value, so use res as the return value of the wrapper.

#3, if the function being modified takes parameters
import time
def timmer(func) :
    def warpper(*args,**kwargs) : An intermediate function needed to avoid the function being run twice
        start_time= time.time()
        res=func(*args,**kwargs)
        end_time =time.time()
        print("cost time--->:",end_time-start_time)
        return res
    return warpper

@timmer #@timmer <--> test=timmer(test)
def test(name) :
    time.sleep(1)
    print("in the test.my name is %s."%name)
    return "This is test' result"

test(name)
Copy the code

Here we go: Advanced Python: Recursive functions and decorators for Python (emphasis)! Share the end, go and try it!


🎉 finally

  • For more references, see here:Chen Yongjia’s blog

  • Like the small partner of the blogger can add a concern, a thumbs-up oh, continue to update hey hey!