SoFunction
Updated on 2024-11-15

Examples of using closures and decorators in python

function parameter

In python, functions can be used as arguments

def func01():
    print("func01 is show ......")


# func01()
# The function name holds the address of the space where the function is located.
# print(func01)
# Function names can also be assigned like normal variables
# func02 = func01
# func02()

def foo(func):
    func()


foo(func01)

Compositional conditions for closures

1. On the premise of function nesting (function inside the function and then define the function)
2. The internal function uses the variables of the external function (also including the parameters of the external function)
3. The external function returns the internal function

# Conditions for the composition of closures.
# 1 in the context of function nesting (function inside function redefining function)

def func_out(num1):
    def func_inner(num2):
        # 2 Internal function uses variables of external function (also includes parameters of external function)
        num = num1 + num2
        print("The value of num is", num2)

    # 3 The external function returns the internal function
    return func_inner


# Create closure instances
f = func_out(10)
# Execute closures
f(1)
f(2)

Basic closure usage

# External functions
def config_name(name):
    # Internal functions
    def say_info(info):
        print(name + ":" + info)

    return say_info
tom = config_name("tom")
tom("Hello.")
tom("Are you there?")

jerry = config_name("jerry")
jerry("Hello.")
jerry("I'm here.")

# External functions
def config_name(name):
    # Internal functions
    def say_info(info):
        print(name + ":" + info)

    return say_info


tom = config_name("tom")
tom("Hello.")
tom("Are you there?")

jerry = config_name("jerry")
jerry("Hello.")
jerry("I'm here.")

Use of the nonloal keyword

1. nonlocally declared variables refer to existing identifiers of declared variables in the nearest outside function, but not global variables. This is important because the default behavior of binding is to search the local namespace first. nonlocally declared variables only work locally and are invalidated when they leave the enclosing function.
2. Non-local declarations are not like global declarations, we must declare the variable beforehand in front of the wrapper function
3. Non-local declarations cannot conflict with locally scoped declarations

# External functions
def func_out(num1):
    # Internal functions
    # aaa = 10

    def func_inner(num2):
        nonlocal num1
        num1 = num2 + 10
    print(num1)
    func_inner(10)
    print(num1)

    return func_inner
# num1 = 10
# f = func_out(10)
# call closure = internal function num2 = 10
# f(10)

func_out(10)

Base code implementation (decorators)

# 1. Define a decorator (decorators are essentially closures)
def check(fn):
    def inner():
        print("Login Authentication")
        fn()

    return inner

# Functions that need to be decorated
def comment():
    print("Post a comment.")

# 2 Decorate a function using a decorator (add a login function)
comment = check(comment)
comment()

Basic use of decorators

# 1 Define a decorator (decorators are essentially closures)
def check(fn):
    def inner():
        print("Please log in first.")
        fn()

    return inner
# 2 Decorate functions using decorators (add a login function)
# The interpreter encounters @check and immediately executes comment = check(comment)

@check
def comment():
    print("Post a comment.")
comment()

Use of decorators

import time
# 1 Defining Decorators
def get_time(fn):
    def inner():
        start = ()
        fn()
        end = ()

        print("Time:", end - start)

    return inner

# 2 Decorative Functions
# Functions to be decorated
@get_time
def func():
    for i in range(100000):
        print(i)
func()

Use of decorators with parameters

# Define the decorator
def logging(fn):  # fn = sum_num
    def inner(a, b):
        fn(a, b)

    return inner  # sum_num = inner

# Decorate functions with decorators
@logging
def sum_num(a, b):
    result = a + b
    print(result)
sum_num(1, 2)

Decorators with return values

# Define the decorator
def logging(fn):  # fn = sum_num
    def inner(a, b):
        result = fn(a, b)
        return result

    return inner  # sum_num = inner

# Decorate functions with decorators
@logging
def sum_num(a, b):
    result = a + b
    return result
result = sum_num(1, 2)
print(result)

Decorators with indeterminate length parameters

# Define the decorator
def logging(fn):  # fn = sum_num
    def inner(*args, **kwargs):
        fn(*args, **kwargs)

    return inner  # sum_num = inner

# Decorate functions with decorators
@logging
def sum_num(*args, **kwargs):
    print(args, kwargs)
sum_num(1, 2, 3, age="18")

Use of decorators with parameters

# Decorator
def logging(flag):  # flag = "+"

    # External functions
    def decorator(fn):
        # Internal functions
        def inner(num1, num2):
            # Judgment process
            if flag == "+":
                print("--Working on the addition calculations--")
            elif flag == "-":
                print("--Working on subtraction calculations--")
            result = fn(num1, num2)
            return result

        return inner

    # Return the decorator
    return decorator
# Functions decorated by decorators with arguments
@logging('+')  # 1 logging("+") 2 @decorator now functions as a decorator
def add(a, b):
    result = a + b
    return result
# Execute functions
result = add(1, 3)
print(result)

Use of class decorators

# Define class decorators
class Check(object):
    def __init__(self, fn):
        self.__fn = fn

    def __call__(self, *args, **kwargs):
        print("Login")
        self.__fn()
@Check
def comment():
    print("Post a comment.")
comment()

to this article on the use of closures and decorators in python is introduced to this article, more related python closures and decorators content please search for my previous articles or continue to browse the following related articles I hope you will support me in the future more!