首页 > 解决方案 > 处理类内的错误,但在其他脚本中引发?

问题描述

我正在寻找一种合理且实用的方法来在类实例中存储不同的错误和/或异常(即IOError, ValueError,<CustomError>等),但避免raise立即使用它们。相反,我想以某种方式将它们传达给import-ed 并首先创建类实例的脚本,raise以及那里的错误和异常。

我不是在寻找有关如何捕获异常的策略。对于我的自定义异常,我使用类!

有没有通用的方法?

谢谢。

标签: pythonpython-2.7classerror-handling

解决方案


您可以定义一个“容器/收集器”类,其中包含您的自定义异常(当然,不引发)。在我的示例中,这个收集器调用就是MyExceptions类。

您可以将唯一异常定义为从相关内置异常继承的类。您可以在此页面上找到内置异常和异常结构(页面底部):https ://docs.python.org/2/library/exceptions.html

唯一异常的基本语法:

class MyException1(BaseException):
    """
    Exception is inherited from 'BaseException'.
    """
    def __str__(self):
        return "This is my Exception1. Inherited from 'BaseException'"

__str__您可以使用或魔术方法设置异常消息__repr__(我__str__在示例中使用了 )。这意味着,在上面的示例中,如果您引发MyException1异常,那么回溯中的消息将是This is my Exception1. Inherited from 'BaseException'. 您可以在以下页面上阅读有关这些魔术方法的更多信息:https ://stackoverflow.com/a/2626364/11502612

my_exceptions.py:

class MyExceptions(object):
    """
    Collector class of Unique Exceptions
    """

    class MyException1(BaseException):
        """
        Exception is inherited from 'BaseException'.
        """
        def __str__(self):
            return "This is my Exception1. Inherited from 'BaseException'"

    class MyException2(Exception):
        """
        Exception is inherited from 'Exception'.
        """
        def __str__(self):
            return "This is my Exception2. Inherited from 'Exception'"

    class MyValueError(ValueError):
        """
        Exception is inherited from 'ValueError'.
        """
        def __str__(self):
            return "This is my MyValueError. Inherited from 'ValueError'"

    class AttributeError(BaseException):
        """
        Redefined 'AttributeError'. Inherited from 'ValueError'
        """
        def __str__(self):
            return "Redefined 'AttributeError'. Inherited from 'ValueError'"

正如您在上面看到的,我的异常收集器类是MyExceptions. 这个类包含其他类,实际上这些是唯一的例外。我写了更多类型的异常。独特的异常继承自不同的内置异常,最后一个显示了如何重新定义内置异常(或多或少)。

这些异常的用法(test.py):

import my_exceptions


def raise_my_exception1():
    raise my_exceptions.MyExceptions.MyException1


def raise_my_exception2():
    raise my_exceptions.MyExceptions.MyException2


def raise_my_value_error():
    raise my_exceptions.MyExceptions.MyValueError


def raise_my_attribute_error():
    raise my_exceptions.MyExceptions.AttributeError


def raise_original_attribute_error():
    raise AttributeError("This is the original (built-in) AttributeError exception")


function_list = [
    raise_my_exception1,
    raise_my_exception2,
    raise_my_value_error,
    raise_my_attribute_error,
    raise_original_attribute_error,
]

for func in function_list:
    try:
        func()
    except BaseException as e:
        print(e)

正如您在上面test.py的文件中看到的,我已将该my_exceptions.py文件作为 Python 模块导入(导入 my_exceptions)。函数中引发了独特的异常。您可以访问例外情况:<Module.CollectorClass.Exception>。最后一个raise_original_attribute_error函数使用自定义消息引发内置异常AttributeError(它显示了如何将自己的AttributeError异常和内置异常分开AttributeError)。该function_list列表包含函数的引用(使用此解决方案,我可以在 for 循环中调用该函数,而无需一个接一个地调用它们)。在 for 循环中,我定义了一个try/except结构并调用函数。我使用了BaseException内置异常,因为它是 Python 中更广泛的异常。

脚本的输出:

>>> python2 test.py 
This is my Exception1. Inherited from 'BaseException'
This is my Exception2. Inherited from 'Exception'
This is my MyValueError. Inherited from 'ValueError'
Redefined 'AttributeError'. Inherited from 'ValueError'
This is the original (built-in) AttributeError exception

您可以在 try/except 中捕获自己的异常(与其他异常分开):

import my_exceptions


def raise_my_exception1():
    raise my_exceptions.MyExceptions.MyValueError


def raise_other_exception():
    raise Exception("Unexpected exception")

for func in [raise_my_exception1, raise_other_exception]:
    try:
        func()
    except my_exceptions.MyExceptions.MyValueError as e:
        print(e)
        print("Handled exception. Do nothing!")
    except Exception as e:
        print(e)
        print("Not handled exception. Raise it!")
        raise e

输出:

>>> python2 test.py 
This is my MyValueError. Inherited from 'ValueError'
Handled exception. Do nothing!
Unexpected exception
Not handled exception. Raise it!
Traceback (most recent call last):
  File "test.py", line 20, in <module>
    raise e
Exception: Unexpected exception

当然,你有很多选择来使用这个自己的异常收集器。

您可以从异常收集器类创建一个实例:

import my_exceptions

exception_collector = my_exceptions.MyExceptions()


def raise_my_exception1():
    raise exception_collector.MyValueError

如果你是一个严格的OOP开发者,你可以从你的异常类继承你的“功能”类。在这种情况下,您可以将异常用作“实例异常”(带有self)。可能这就是你要找的东西!

例子:

import my_exceptions


class FunctionalClass(my_exceptions.MyExceptions):
    def raise_my_exception1(self):
        raise self.MyValueError

    def raise_other_exception(self):
        raise Exception("Unexpected exception")


functional_instance = FunctionalClass()

for func in [functional_instance.raise_my_exception1, functional_instance.raise_other_exception]:
    try:
        func()
    except my_exceptions.MyExceptions.MyValueError as e:
        print(e)
        print("Handled exception. Do nothing!")
    except Exception as e:
        print(e)
        print("Not handled exception. Raise it!")
        raise e

输出:

>>> python2 test.py 
This is my MyValueError. Inherited from 'ValueError'
Handled exception. Do nothing!
Unexpected exception
Not handled exception. Raise it!
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    raise e
Exception: Unexpected exception

推荐阅读