【问题标题】:How to count each exception by itself如何单独计算每个异常
【发布时间】:2021-04-07 10:42:27
【问题描述】:

我目前一直在创建自己的异常等:

# -*- coding: utf-8 -*-

# ------------------------------------------------------------------------------- #

"""
exceptions
~~~~~~~~~~~~~~~~~~~
This module contains the set of multiple exceptions.
"""


# ------------------------------------------------------------------------------- #


class RequestsException(Exception):
    """
    Base exception class
    """


class TooManyFailedRequests(RequestsException):
    """
    Raise an exception for FailedRequests
    """


class TooManyTimedOut(RequestsException):
    """
    Raise an exception for TimedOut
    """

我创建了一个有计数器的脚本:

import time

import requests
from requests.exceptions import ConnectionError, ReadTimeout, Timeout

from lib.exceptions import (
    TooManyFailedRequests,
    TooManyTimedOut
)


def send_notification(msg):
    print(f"Sending notification to discord later on! {msg}")


class simpleExceptionWay:
    """
    Counter to check if we get exceptions x times in a row.
    """

    def __init__(self):
        self.failedCnt = 0

    def check(self, exception, msg):
        self.failedCnt += 1
        if self.failedCnt > 2:
            send_notification(msg)
            raise exception(msg)

    def reset(self):
        self.failedCnt = 0


# Call this function where we want to check
# simpleException.check(exception, msg)
simpleException = simpleExceptionWay()


def test():
    """
    We also want to count in here if we ever reach in here.
    """

    return "Hello world"


def setup_scraper(site_url):
    session = requests.session()

    while True:

        try:
            response = session.post(site_url, timeout=5)

            if response.ok:
                simpleException.reset()
                exit()

            if response.status_code in {429, 403, 405}:
                print(f"Status -> {response.status_code}")

                simpleException.check(
                    TooManyFailedRequests,
                    {
                        'Title': f'Too many {response.status_code} requests in a row',
                        'Reason': str(),
                        'URL': str(site_url),
                        'Proxies': str(
                            session.proxies
                            if session.proxies
                            else "No proxies used"
                        ),
                        'Headers': str(session.headers),
                        'Cookies': str(session.cookies)
                    }
                )

                time.sleep(3)
                continue

        except (ReadTimeout, Timeout, ConnectionError) as err:

            simpleException.check(
                TooManyTimedOut,
                {
                    'Title': f'Timed out',
                    'Reason': "Too many timed out",
                    'URL': str(site_url),
                    'Proxies': str(
                        session.proxies
                        if session.proxies
                        else "No proxies used"
                    ),
                    'Headers': str(session.headers),
                    'Cookies': str(session.cookies)
                }
            )
            continue


if __name__ == "__main__":
    setup_scraper("https://www.google.se/")

我目前的问题是我只有 1 个计数器一起计数,我想知道我该怎么做,例如,如果我们连续 100 次达到 TooManyTimedOut,那么我们想要加注,当我们达到 TooManyFailedRequests连续 5 次,那么我们应该引发异常。有可能吗?

【问题讨论】:

    标签: python-3.x exception counter


    【解决方案1】:

    您可以使用 type() 函数获取异常的类型,然后使用该类型的 name 属性将其名称作为字符串获取。然后,您可以将其存储在一个字典中,以跟踪异常计数。

    class simpleExceptionWay:
        """
        Counter to check if we get exceptions x times in a row.
        """
    
        def __init__(self):
            self.exception_count = {}
    
        def check(self, exception, msg):
            exception_name = exception.__name__
    
            # the dict.get() method will return the value from a dict if exists, else it will return the value provided
            self.exception_count[exception_name] = self.exception_count.get(exception_name, 0) + 1
              
            if self.exception_count[exception_name] > 2:
                send_notification(msg)
                raise exception(msg)
    
        def reset(self):
            self.exception_count.clear()
    

    【讨论】:

    • 嗯是的,但是例如,如果我希望特定类型在达到 100 时触发引发异常?我们如何做到这一点?现在看来,我们现在所做的每一个异常都会在第二次循环后触发? - 我也不太确定exception_name = type(exception).__name__ 将如何返回名称,似乎它只是为我返回名称“类型”
    • 如果你想检查特定的异常,你可以使用if self.exception_count["TooManyTimedOut"] == 100,至于name,它应该可以工作。
    • 哦,那是真的,type(exception).__name__ 怎么样 - 看起来它只为我返回了“类型”这个词 >>> print(self.exception_count, exception_name) >>> {'type': 1} type
    • 尝试这样做:int.__name__,你会得到一个字符串,如果你有一个持有对象引用的变量,你可以使用type(myvar)获取类型,然后使用__name__获取类名作为字符串。 a = {"b": 20}; print(type(a).__name__)
    • 哦,既然您使用的是check(exception, msg),您可以创建另一个参数allowed_count 或类似的东西,然后您可以在if 语句中使用它来使您的代码更小:if self.exception_count[exception_name] >= allowed_count:跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 2021-06-19
    相关资源
    最近更新 更多