python ornaments

Decorator concept

Passing a function as an argument to another function returns an alternative version of the function
The way to dynamically add functionality during code execution, called decorators, is essentially a function that returns a function with the purpose of adding functionality to the function without changing the original function.

Decorator 1

1. A function is also an object, and a function object can be assigned to a variable, so it can also be called through a variable.
Definition of function say ()
def fun():
    print('hello python')
Assuming you want to enhance the capabilities of the say() function, such as making positive and negative judgments on arguments when calling a function, but you don't want to modify the definition of say(), you can add functionality while the code is running by using an adorner.
It can be defined as follows:
def outer(f):
    def inner():
        print('@@@@@@@')
        f()
        print('!!!!')
    return inner
Look at the outer() function above, because it is a decorator, so it takes a function as a parameter and returns a function.Place decorator at function definition with python's syntax sugar
@outer
def fun():
    print('hello python')

Putting the syntax sugar @outer at the definition of the fun() function is equivalent to executing a statement:
Since outer() is only a decorator and returns a function, the original fun() function still exists, but now the fun() variable with the same name points to a new function, so calling your fun() will execute the new function, that is, the inner() function returned in the outer() function.

fun = outer(fun)

Calling the fun() function not only runs fun() itself, but also prints out new content:

Example:

def outer(f):
    def inner(age):
        if age <=0:
            age = 0
        f(age)
    return inner
@outer #Grammatical Sugar
def say(age):
    print('%d years old' %(age))

Executing say (-12) results in

Decorator 2

Decorator implements a function timer
1. What if the decorated function has a return value?
2. How do I keep the function name and help documentation information of the decorated function?Decorator implements a function timer
1. What if the decorated function has a return value?
2. How do I keep the function name and help documentation information of the decorated function?

import random
import string
import time
li = [random.choice(string.ascii_letters) for i in range(100)]

def timeit(fun):
    #@functools.wraps(fun)
    def wrapper(*args,**kwargs):# Receive variable and keyword parameters
        """This is an ornament timeit"""
        # Before function execution
        start_time = time.time()
        # Execute Function
        res = fun(*args,**kwargs)
        # After function execution
        stop_time = time.time()
        print('The run event is:%.6f' %(stop_time-start_time))
        return res
    return wrapper
# @timeit
# def con_add():
#     s = ''
#     for i in li:
#         s += (i + '')
#     print(s)
# @timeit
# def join_add():
#     print(','.join(li))
#
# con_add()
# join_add()


@timeit
def fun_list(n):
    """This is fun_list function"""
    return [2 * i for i in range(n)]
@timeit
def fun_map(n):
    """This is fun_map Function Decoration timeis decorate"""
    return list(map(lambda x:x*2,range(n)))
# fun_list(10000)
# fun_map(10000)
print(fun_list.__name__)
print(fun_list.__doc__)

print(fun_map.__name__)
print(fun_map.__doc__)

Decoration 3

To create an ornament, the following requirements are required:

  1. Create an add_log decorator, and the decorated function prints the log information;
  2. The log format is: [string time] function name: xxx, run time: xxx,
    Run Return Value Result: xxx
# import time
# print(time.ctime())

import time
import functools

def add_log(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):

        start_time = time.time()
        res = func(*args,**kwargs)
        end_time = time.time()
        print('[%s] Function name:%s,Runtime:%.6f,Result of running the return value'
              ':%d' %(time.ctime(),func.__name__,
                      end_time-start_time,res))
        return res
    return wrapper
@add_log
def add(x,y):
    time.sleep(1)
    return x+y

add(1,10)

Decorator 4

  1. Basic (parameterless decorator)
    Write the decorator required_ints under the following conditions:
    1). Ensure that every parameter received by the function is an integer;
    2). If the parameter is not an integer, print TypeError: the parameter must be an integer
import functools
def required_ints(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):  # args=(1,2,..)
        for i in args:
            # if isinstance(i,int):
            #     pass
            # else:
            #     print('Not all arguments to the function are int')
            #     break
            if not isinstance(i, int):
                print('Not all parameters of a function are int type')
                break
        else:
            res = func(*args, **kwargs)
            return res

    return wrapper
@required_ints
def add(a, b):
    return a + b
@required_ints
def mymax(a,b,c,d):
    return max(a,b,c,d)

print(add(1,2.0))

To create an ornament, the following requirements are required:

  1. Create an add_log decorator, and the decorated function prints the log information;
  2. The log format is: [string time] function name: xxx, run time: xxx, run return value result: XXX
import time
import functools
def log(kind):
    def add_log(func):
        @functools.wraps(func)
        def wrapper(*args,**kwargs):

            start_time = time.time()
            res = func(*args,**kwargs)
            end_time = time.time()
            print('<%s> [%s] Function name:%s,Runtime:%.6f,Result of running the return value'
                  ':%d' %(kind,time.ctime(),func.__name__,
                          end_time-start_time,res))
            return res
        return wrapper
    return add_log

@log('local2')
def add(x,y):
    time.sleep(1)
    return x+y

add(1,10)

Decorator 5

['root','admin','redhat']
id id+vip
Scenarios for multiple decorators:
Multiple decorators will be used to verify successful login before verifying that permissions are sufficient

import functools
import inspect


def is_login(fun):
    @functools.wraps(fun)
    def warapper(*args, **kwargs):  # ('admin',)
        if args[0] in login_session:
            temp = fun(*args, **kwargs)
            return temp
        else:
            print('Error:%s No landing success' % (args[0]))

    return warapper


def is_admin(fun):
    @functools.wraps(fun)
    # nspect.getcallargs returns a dictionary
    #  key:formal parameter value:corresponding argument
    def wrapper(*args, **kwargs):
        inspect_res = inspect.getcallargs(fun, *args, **kwargs)
        print('inspect The return value of:%s' % (inspect_res))
        if inspect_res.get('name') == 'root':
            temp = fun(*args, **kwargs)
            return temp
        else:
            print('not root user,no permisson add user')

    return wrapper


login_session = ['root', 'admin', 'redhat']



@is_login
@is_admin
def add_user(name):
    print('add_user~~')


add_user('root')

Decorator 6

  1. Basic (parameterless decorator)
    Write the decorator required_ints under the following conditions:
    1). Ensure that every parameter received by the function is an integer;
    2). If the parameter is not an integer, print TypeError: the parameter must be an integer
import functools
def required_ints(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):  # args=(1,2,..)
        for i in args:
            # if isinstance(i,int):
            #     pass
            # else:
            #     print('Not all arguments to the function are int')
            #     break
            if not isinstance(i, int):
                print('Not all parameters of a function are int type')
                break
        else:
            res = func(*args, **kwargs)
            return res

    return wrapper
@required_ints
def add(a, b):
    return a + b
@required_ints
def mymax(a,b,c,d):
    return max(a,b,c,d)

print(add(1,2.0))

Decorator 7

To create an ornament, the following requirements are required:

  1. Create an add_log decorator, and the decorated function prints the log information;
  2. The log format is: [string time] function name: xxx, run time: xxx, run return value result: XXX
import time
import functools

def log(kind):
    def add_log(func):
        @functools.wraps(func)
        def wrapper(*args,**kwargs):

            start_time = time.time()
            res = func(*args,**kwargs)
            end_time = time.time()
            print('<%s> [%s] Function name:%s,Runtime:%.6f,Result of running the return value'
                  ':%d' %(kind,time.ctime(),func.__name__,
                          end_time-start_time,res))
            return res
        return wrapper
    return add_log

@log('local2')
def add(x,y):
    time.sleep(1)
    return x+y

add(1,10)

Decorator 8

  1. Upgraded version (decorator with parameters)
    Write the decorator required_types under the following conditions:
    1). When the decorator is @required_types(int,float), make sure that every parameter the function receives is
    int or float type;
    2). When the decorator is @required_types(list), make sure that every parameter received by the function is a list type;
    3. When the decorator is @required_types(str,int), make sure that each parameter received by the function is of type STR or int;
    4). If the parameter does not meet the criteria, print TypeError: the parameter must be of type XXX
import functools
def required_type(*kind):
    def required(fun):
        @functools.wraps(fun)
        def wrapper(*args,**kwargs):
            for i in args:
                if not  isinstance(i,kind):
                    print('Not all parameters of a function',kind)
                    break
            else:
                res = fun(*args,**kwargs)
                return res

        return wrapper
    return required

@required_type(int)
def add(a, b):
    return a + b

print(add(1,1.2))

Keywords: Python Lambda

Added by amazing on Thu, 19 Sep 2019 06:25:01 +0300