python 装饰器实践,实现定时函数和失败异常重复调用

python 装饰器实践,实现定时函数和失败异常重复调用

执行请求或函数,出现异常情况下指定重复执行次数
可以作为一个包调用
方法 get()和post 做请求,execcunt = 指定请求失败再次请求次数
方法loopExecution作为装饰器,循环执行函数,execcunt = 指定异常再次执行次数

#函数异常情况下再次执行,执行次数


import traceback
def loopExecution(func):
    def wrapper(*args,**kwargs):
        count = kwargs.pop("execcount", 1)
        try:
            res = func(*args,**kwargs)
        except Exception as err:
            for i in range(count):
                try:
                    res = func(*args,**kwargs)
                    if isinstance(res,Exception):
                        return res
                except Exception as err:
                    pass
            #失败到达限定值返回异常信息
            return traceback.format_exc()
            # return None
        return res
    return wrapper

@loopExecution
def func():
    print("我是一个函数")
    raise Exception("执行失败了")

if __name__ == '__main__':

    data = func(execcount=6)
    print("多次失败情况下返回的数据:",data)

通用请求,指定请求次数,将其作为一个包调用,如包名为my_request
import my_reqeust
response = my_request.get(url)

import time
import requests
import traceback
from requests import Session
from functools import partial

session = Session()
traceback_info = None

def outer(func):
    def wrapper(*args,**kwargs):
        count = kwargs.pop("execcount", 1)
        res = func(*args,**kwargs)
        if isinstance(res, Exception):
            for i in range(count):
                print(i)
                res = func(*args,**kwargs)
                if not isinstance(res, Exception):
                    break
            if isinstance(res, Exception):
                return None
        return res
    return wrapper


@outer
def publicRequsts(*args,**kwargs):
    """通用请求方法"""
    method = args[0] if len(args) is 1 else kwargs.pop("method", "GET")
    if not method in ("GET","POST"):
        raise Exception("The request method is illegal")
    url = args[1] if len(args) is 2 else kwargs.pop("url", None)
    if url is None or not isinstance(url,str) or not "http" in url:
            raise Exception("The URL is illegal")
    try:
        response = session.request(method, url,**kwargs)
        print("="*10)
    except Exception as err:
        global traceback_info
        traceback_info = traceback.format_exc()
        return err
    return response

get = partial(publicRequsts, "GET")
post = partial(publicRequsts, "POST")

使用线程对执行函数限制执行时间,可不加定时为非阻塞,加定时间到会强制停止线程

from threading import Thread
import threading
import inspect
import ctypes

def _async_raise(tid, exctype):
    """raises the exception, performs cleanup if needed"""
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)

def timelimited(exectime=None):
    def decorator(function):
        def decorator2(*args, **kwargs):
            time_out = exectime if not exectime is None else kwargs.pop("exectime",None)
            if time_out is None:
                return Exception("exec time param missing ")
            class TimeLimited(threading.Thread):
                def __init__(self, _error=None, ):
                    Thread.__init__(self)
                    self._error = _error
                    self._result = None
                def run(self):
                    try:
                        result = function(*args, **kwargs)
                        if result is None:
                            self._result = True
                        else:
                            self._result = result
                    except Exception as err:
                        self._error = Exception(err)
            t = TimeLimited()
            t.setDaemon(True)
            t.start()
            if not time_out is False:
                t.join(time_out)
                if isinstance(t._error, Exception):
                    return t._error
                else:
                    if t._result is None:
                        stop_thread(t)
                        return Exception("Time out!")
                    else:
                        return t._result
        return decorator2
    return decorator

@timelimited(exectime=3)# 设置运行超时时间S,优先使用,exectime=False是不加定时
def func():

    time.sleep(5)
    print("==========")
    print("==========")
    print("==========")
    print("==========")
    return "aaaa"

if __name__ == "__main__":
	print(func())
	time.sleep(4)
	print(threading.enumerate())
	time.sleep(6)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_JackSparrow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值