One 、 Decorator 【 Focus on mastering 】
Iterable: Iteratable object
Iterator: iterator
generator: generator
decorator: Decorator
Concept : A function is known , If you need to add new functions to this function , But I don't want to change the original function , stay Python in , This mechanism of dynamic execution during code execution is called a decorator 【Decorator】
The function of ornaments : Add additional functionality to existing functions or classes
The essence of ornaments : It's actually a closure , Internal functions access variables in external functions 【 function 】
1. Basic usage
# 1. Closure
def func1(n):
def func2():
print(n)
func2()
func1(10)
def func1(n):
def func2():
print(n)
return func2
f = func1(10) # f = func2
f()
# 2. Basic grammar of decorators
def test(): # 9
print(" There's nothing I can do , Stick to moving yourself ")
# Basic writing steps for decorators
# a. Writing closures
# b. Setting parameters for external functions , This parameter represents the function to be decorated
def outter1(func): # 2
def inner1(): # 3 7
# c. Call the original function 【 Accessing variables in external functions in internal functions 】
func() # Call the original function test # 8 10
# d. Add new features
print("new~~~~")
return inner1 # 4
# e. Call the decorator 【 External function 】
f1 = outter1(test) # func = test f1 = inner1 # 1 5
# f. Call the decorator's internal function
# print(f1)
f1() # inner1() # 6 11
# 1. The original function has parameters
def get_age(age):
print(f" Age :{age}")
# demand : Write a decorator , Need to give get_age Function age check
def check_age1(func):
def inner1(n):
# Add new features : Check age
if n < 0:
n = -n
# Call the original function
func(n)
return inner1
f1 = check_age1(get_age)
f1(10)
f1(-10)
# Be careful : If the original function has parameters , Add new functions to internal functions , If you need to perform corresponding operations on the parameters in the original function
# You can set parameters to the inner function
# 2. Common forms of decorators
# Be careful : Decorator is essentially a function , For decorators or primitive functions , Parameters 【 Default parameters , Key parameters , Indefinite length parameter 】 And return values can be used normally
# a.
def test1():
print("test~~~111")
def wrapper1(func):
def inner1():
print("new~~~1111")
func()
return inner1
f1 = wrapper1(test1)
f1()
print("*" * 50)
# b
def test1(n):
print("test~~~222",n)
def wrapper1(func):
def inner1(n):
print("new~~~2222")
func(n)
return inner1
f1 = wrapper1(test1)
f1(10)
print("*" * 50)
# c
def test1(n):
print("test~~~333",n)
return 66
def wrapper1(func):
def inner1(n):
print("new~~~3333")
r = func(n)
print(r)
return inner1
f1 = wrapper1(test1)
f1(10)
print("*" * 50)
# d
def test1(n):
print("test~~~444",n)
return 66
def wrapper1(func):
def inner1(n):
print("new~~~4444")
r = func(n)
print(r)
return 'abc'
return inner1
f1 = wrapper1(test1)
r1 = f1(10)
print(r1)
print("*" * 30)
# [email protected]
# explain :@xxx,xxx Indicates the name of the decorator , It is actually the function name of the external function
# grammar : take @xxx Apply before the declaration of the function that needs to be decorated
# Be careful : Use @xxx Use decorators , There must be a decorator first , And then you can use it
def check_age2(func):
print(" External function ")
def inner2(n):
print(" Internal function ~~~~")
if n < 0:
n = -n
func(n) # Call the original function
print(" External function ~~~~over")
return inner2
@check_age2 # amount to f1 = check_age2(get_age2), Call the decorator's external function
def get_age2(age):
print(f" Age :{age}")
get_age2(-18) # amount to f1(-18), Call the decorator's internal function
"""
working principle :
First step :@check_age2
a.func---->get_age2 primary
b.get_age2---->inner2
The second step :get_age2(-18)
a. call inner2, Then go to func(), It means to call the original function
"""
# The same decorator decorates multiple functions at the same time , It is equivalent to adding the same new function to multiple functions at the same time
# Be careful : If you need the same decorator to decorate multiple functions , In order to meet the needs of the parameters of different functions , The decorator's internal function is set to an indefinite length parameter
def wrapper(func):
def inner(*args,**kwargs): # pack
# print(args,kwargs)
# print(*args,**kwargs)
func(*args,**kwargs) # unpacking
print("new!!!!!")
return inner
@wrapper
def f1():
print("111111")
@wrapper
def f2(a,b):
print("22222",a,b)
@wrapper
def f3(num1,num2,num3,num4):
print("3333")
f1()
f2(23,10)
f3(34,6,8,9)
# 【 Interview questions 】 practice : Write a decorator , You can count the execution time of any function
import time
# Time stamp : Get the current time distance 1970.1.1 00:00:00 The number of seconds
# print(time.time())
def get_time(func):
def inner(*args,**kwargs):
start = time.time()
func(*args,**kwargs)
end = time.time()
return round(end - start,3)
return inner
@get_time
def test():
for i in range(100000):
pass
r1 = test()
print(r1)
@get_time
def test1(n):
for i in range(n):
pass
r2 = test1(1000000)
print(r2)
2. Advanced usage
# Multiple decorators decorate the same function
# effect : Add several different functions to the same function at the same time
# a
def wrapper1(func1):
def inner1(*args,**kwargs):
print(" The first 1 A decorator ~~~~~start")
func1(*args,**kwargs)
print(" The first 1 A decorator ~~~~~end")
return inner1
def wrapper2(func2):
def inner2(*args,**kwargs):
print(" The first 2 A decorator ~~~~~start")
func2(*args,**kwargs)
print(" The first 2 A decorator ~~~~~end")
return inner2
def wrapper3(func3):
def inner3(*args,**kwargs):
print(" The first 3 A decorator ~~~~~start")
func3(*args,**kwargs)
print(" The first 3 A decorator ~~~~~end")
return inner3
@wrapper1
@wrapper2
@wrapper3
def test():
print("test~~~~~")
test()
"""
working principle :
The first part : Call external functions
@wrapper1
@wrapper2
@wrapper3
def test():
print("test~~~~~")
a. call wrapper3,func3---->test primary ,test---->inner3
b. call wrapper2, func2--->test【inner3】,test---->inner2
c. call wrapper1, func1--->test【inner2】,test---->inner1
The second part : Call the inner function
test()
a.inner1--->func1【inner2】
b.inner2--->func2【inner3】
c.inner3--->func3【test primary 】
"""
Two 、 Function recursion
In actual development , Less recursion , Recursion is not as efficient as looping
"""
Recursive function : If a function , In the function body, the call itself
Problems needing attention when using recursion :
a. You need to find a threshold , You can make recursion stop at a suitable time
b. There is a certain rule between two adjacent calls of a function
"""
# 1. Malicious call
# def a():
# print('aaaa')
# a()
# a()
# 2. The correct use of recursion
# a. demand 1: Report a number 【 Location 】, Get the corresponding number in the Fibonacci sequence
"""
1 2 3 4 5 6 7 8 9 10 11.....
1 1 2 3 5 8 13 21 34 55 89
"""
"""
law :
a. The first 1 Number and number 2 The number is fixed , All for 1
b. The first n Number = The first n-1 Number + The first n - 2 Number
"""
def func(n):
print(n)
if n == 1 or n == 2:
return 1
else:
return func(n - 1) + func(n - 2)
r = func(11)
print(r)
# b. demand : seek 1~ The sum of integers between certain numbers
"""
law :
a. If n by 1, The result is directly 1
b. If n>=2, The result is 1~n-1 The sum of numbers between + n
"""
def fn(n):
print(n)
if n == 1:
return 1
else:
return fn(n - 1) + n
r = fn(100)
print(r)