Higher-order functions
A higher-order function satisfies any of the following conditions:
- You can accept functions as arguments
- You can return a function as a return value
########## accepts the function as argument ##########
f = abs
def add(x, y, f) :
return f(x) + f(y)
print(add(-1, -2, f))
########## returns the function as the return value ##########
def hello() :
print('Hello World')
def wrapper(func) :
return func
f = wrapper(hello)
f()
Copy the code
Closure
Let’s look at the scope of the variable:
- L: internal scope of the local function
- If you want additional recommendations on this. E: Between inside and inside functions.
- G: global Global scope
- B: Build-in built-in scope (members automatically imported by the parser)
The priority of the variable scope lookup process is LEGB(L>E>G>B).
def func(lst) :
def in_func() :
return len(lst)
return in_func
f = func([1.2.3])
print(f())
Copy the code
A closure is a case in which an inner function refers to a variable of the outer function (parameters are also variables) and then returns the inner function.
A decorator
What if we define a function that wants to add functionality dynamically at run time, but we don’t want to change the function code? We think of higher-order functions, which can take functions as arguments and return functions, so can we take a function, wrap it, and return a new function, so we can solve this problem, as follows:
def f1(x) :
return x * 2
# fn is a decorator function implemented as a higher-order function
def fn(f) :
def new_fn(x) :
print('call ' + f.__name__ + '()')
return f(x)
return new_fn
# call
f1 = fn(f1)
print(f1(5))
Copy the code
Python’s built-in @ syntax simplifies the invocation of decorators, as shown below:
@fn
def f1(x) :
return x * 2
Copy the code
A decorator function with no arguments is defined above. Let’s see how decorators with arguments are defined:
def log(prefix) :
def log_decorator (f) :
def wrapper(*args, **kw) :
print('[' + prefix + '] ' + ' call ' + f.__name__ + '()')
return f(*args, **kw)
return wrapper
return log_decorator
@log('NOTICE')
def f1(x) :
return x * 2
print(f1(5))
Copy the code
So the parameterized decorator function returns a new function, which then takes f1() as an argument and returns the new function.
A decorator is a combination of higher-order functions, nested functions, and closures.