【问题标题】:Can I create User-defined Exceptions in a class, instead of creating for every function when needed in python ? Please Advise我可以在类中创建用户定义的异常,而不是在 python 需要时为每个函数创建吗?请指教
【发布时间】:2020-07-12 03:11:34
【问题描述】:

当我在一个类中创建 try-except 时,如图所示出现错误: (在类中创建基于用户的异常的原因是,我可以在需要时在任何函数中重用异常,并且可以引发错误)

class Error(Exception):
   pass
class ValueTooSmallError(Error):
   pass
class ValueTooLargeError(Error):
   pass

import random
class GuessNum(object):
    try:
        def __init__(self):        
            self.number = random.randint(1,50)

        def startGame(self):        
            while True:
               i_num = int(input("Enter a number: "))
               if i_num < self.number:
                   raise ValueTooSmallError
               elif i_num > self.number:
                   raise ValueTooLargeError
               break
    except ValueTooSmallError:
       print("This value is too small, try again!")
       print()
    except ValueTooLargeError:
       print("This value is too large, try again!")
       print()

但是,当我在函数脚本中创建 try-except 时工作正常,但想知道为什么上面的脚本失败了。请指教。

number = 10
while True:
   try:
       i_num = int(input("Enter a number: "))
       if i_num < number:
           raise ValueTooSmallError
       elif i_num > number:
           raise ValueTooLargeError
       break
   except ValueTooSmallError:
       print("This value is too small, try again!")
       print()
   except ValueTooLargeError:
       print("This value is too large, try again!")
       print()
print("Congratulations! You guessed it correctly.")

【问题讨论】:

    标签: python python-3.x exception python-requests python-class


    【解决方案1】:

    在您的课程中,您的 try-except 块正在捕获您的方法定义的潜在错误。如果你想在执行 GuessNum.startGame() 时捕捉东西,你必须在函数中放置 try-except 块。

    【讨论】:

    • 感谢托马斯的回复。你能否详细说明一下声明,如果可能的话,举个对我很有帮助的例子 - “try-except 块正在捕捉你的方法定义的潜在错误:”
    【解决方案2】:

    问题是您使用 try-except 错误。 try-catch 块的目的是处理运行时中的错误,你可能已经知道了。但是,诸如函数或类之类的事物的定义不会在运行时产生错误。如果你的定义是错误的,解释器甚至不会开始它的工作。当你定义一个函数时,你只是告诉它在被调用时要做什么。如果你定义了一个可能会产生错误的函数,比如下面的例子,带有函数定义的代码仍然会运行:

    number_of_oranges = 40
    total_students = 0
    def give_oranges():
            orange_for_each = number_of_oranges/total_students
        return orange_for_each
    
    give_oranges()
    

    这里,当你调用give_oranges() 函数时,它会在大多数情况下工作,除非没有学生,这意味着total_students = 0 会引发ZeroDivisionError 错误。所以我们把调用这个函数的语句放在try-except中。不是函数定义,请注意,因为它只是定义了函数,而没有做任何其他事情。

    number_of_oranges = 40
    total_students = 0
    
    def give_oranges():
            orange_for_each = number_of_oranges/total_students
        return orange_for_each
    try:
        give_oranges()
    except ZeroDivisionError:
        print("There are no students!")
    
    give_oranges()
    

    这一次,如果没有学生,我们将看到 except 块被执行并且“没有学生!”屏幕上。

    现在我们已经清楚了在哪里使用 try-catch,让我们故意犯一个错误,将函数定义本身放在 try catch 中,而不是我们调用它的语句。

    number_of_oranges = 40
    total_students = 0
    
    try:
      def give_oranges():
        orange_for_each = number_of_oranges/total_students
        return orange_for_each
    except ZeroDivisionError:
      print("There are no students!")
    
    give_oranges()
    

    这一次它也引发了错误,但看起来很奇怪:

    Traceback (most recent call last):
      File "main.py", line 11, in <module>
        give_oranges()
      File "main.py", line 6, in give_oranges
        orange_for_each = number_of_oranges/total_students
    ZeroDivisionError: division by zero
    

    似乎我们的 except 块没有像我们预期的那样执行。错误是从调用函数的位置引发的。解释如下:当 Python 解释器读到最后一行时,它已经知道 give_oranges() 方法做了什么,如果这个函数的定义不起作用,它知道该怎么办。函数定义绝对正确,因此没有引发错误,并且 except 块没有任何 ZeroDivisionError 要捕获。只是后来我们使用该函数时,错误再次发生,但这次没有try-except块来捕获确切的语句。

    在您的情况下,您试图涵盖一些定义,而不是您实际调用这些定义的位置。该错误已引发但您没有正确捕获,它正在由 Python 类中的一些内置机制处理。很抱歉在示例中过度使用并且没有直接指出代码中的错误,但是现在您应该更好地了解在哪里不使用 try-excepts 以及在哪里正确使用它。

    【讨论】:

    • 非常感谢您的解释。我现在知道在哪里使用 try catch。我还有一个问题,例如,如果我们在一个类中有 100 个函数,我需要对每个函数进行 try-catch。根据目前对该主题的理解,我需要为每个函数创建 try-catch。所以我在这里感到震惊,为什么我们要创建 100 个 try-catch,为什么我们不能定义基于用户的异常/预定义异常并在需要的每个函数中引发错误。 (由此我们重用异常)。很抱歉提出了多个问题,在我继续之前想确认一下。
    • 我认为你错过了最重要的一点:你不应该使用带有任何定义的 try-catch 机制。您不是在指示解释者在定义中做任何事情,是吗?你只是告诉它,“嘿,你看到这里的代码了吗?我要给它一个名字my_function()。下次我打电话给my_function()时,请运行那个特定的代码。”另一方面,您应该对可能实际失败的语句使用 try catch,例如 my_function() 定义中的语句。根据任务组,您可以有多个 try-catch 块。
    • 至于拥有 100 个函数,这正是 OOP 和其他设计模式的用武之地。显然,这 100 个函数可以分解为一些常见的东西,它们是代码的构建块。您需要在这些块中捕获错误,然后在其他方法中使用它们时已经涵盖了您。当然,您仍然可以在需要时使用更多的 try-catch,但至少您会减少工作量和冗余。如果您需要更多解释,最好再问一个问题和/或阅读 OOP 相关书籍。
    • 感谢 Ratul 的澄清。
    • @VRao 欢迎您!如果这个答案有帮助,您能否将其标记为已接受?
    猜你喜欢
    • 2016-09-08
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多