在函数定义周围使用tryexcept忽略异常处理

2024-06-28 19:50:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我的消息“被0除错误”没有通过,相反我得到了一个正常的ZeroDivisionError。你知道吗

#!/usr/bin/python

t = raw_input("do you want to play a game?[y/n]" )

#r = raw_input("Please enter a number")

#e = raw_input("Please enter a number again")

try:
 def di (a, b):
  return  a/b
except ZeroDivisionError:
 print "Divide by 0 Error"

while t == "y":
  u = raw_input("Please enter / sign ")
  if u == "/":
   r = int(raw_input("Please enter a number"))
  try:
   e = int(raw_input("Please enter a number again"))
   print "the answer is", di(r, e)
   t = raw_input("do you want to play a game?[y/n]" )


  except ValueError:
   t = raw_input( "Invalid input, must be a number. Press yes to continue, no stop")

Tags: toyougamenumberinputplayrawdo
3条回答

TLDR:将异常处理程序移到函数中,异常实际发生的位置:

def di(a, b):
    try:
        return a/b
    except ZeroDivisionError:
        print("Divide by 0 Error")

执行Python中的函数定义,这种执行可能会产生副作用,例如修改对象或引发异常。但是,在定义上只有它的签名会立即运行;它的主体会被存储,并且只有在调用函数时才会运行。你知道吗

>>> def func(arg=print("default evaluated")):
...     print("body evaluated")
...
default evaluated
>>> func
<function __main__.func(arg=None)>
>>> func()
body evaluated

在异常处理程序中定义函数时,此异常处理程序仅接收评估签名时引发的异常。例如,计算默认参数可能会引发ZeroDivisionError

>>> def invalid_def(arg=10/0):
...     pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

这种情况下的异常处理程序很少是您想要的。有条件地定义函数很有用,例如,如果NameError表示依赖项不可用。你知道吗

通常,您希望处理源自函数体的异常。无论何时实际调用函数,都会引发这些问题:

>>> def invalid_call():
...     return 10 / 0
...
>>> invalid_call()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in invalid_call
ZeroDivisionError: division by zero
>>> invalid_call()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in invalid_call
ZeroDivisionError: division by zero

处理此类异常有两种方法:外部方法或内部方法。你知道吗

  • 外部处理需要在每个调用站点上有一个异常处理程序。这更灵活,但需要样板文件,因为每个调用都需要一个异常处理程序。你知道吗

    >>> try:
    ...     invalid_call()
    ... except ZeroDivisionError:
    ...     print("suppressed an external error")
    
  • 内部处理需要正文中的异常处理程序。这是不太灵活,但不需要样板,因为一个异常处理程序涵盖所有情况。你知道吗

    >>> def valid_call():
    ...     try:
    ...         return 10 / 0
    ...     except ZeroDivisionError:
    ...         print("suppressed an internal error")
    

这两种方法都是有效的;选择哪种方法取决于您是更需要可用性还是重用性。值得注意的是,将这两种方法结合起来并不少见:内部处理程序泛化异常,而外部处理程序只期望泛化异常。你知道吗

例如,在允许处理多个操作的情况下:

def div(a, b):
    try:
        return  a / b
    # convert operation-specific exception to general one
    except ZeroDivisionError:
        raise ValueError("Cannot divide by 0")

# may be another operation   add, mul, sub, ...
operation = div

try:
    operation(10, 0)
# only handle exception general to all operations
except ValueError as err:
    print("Invalid values: %s" % err)

仔细看代码:

try:
    def di (a, b):
        return  a/b

except ZeroDivisionError:
    print "Divide by 0 Error"

您的try/except块包含整个函数定义:它专门应用于定义函数。当函数从调用执行时,没有异常块处于活动状态。你知道吗

改用这个:

def di (a, b):
    try:
        return  a/b
    except ZeroDivisionError:
        print "Divide by 0 Error"

我对这个问题的看法(显然很有意思,可以得到多个答案,做得很好)是要记住,在Python中,类和函数定义与大多数其他语句一样执行。你知道吗

try:
    def di (a, b):
        return  a/b
except ZeroDivisionError:
    print "Divide by 0 Error"

说:

“尝试定义一个名为di的函数,该函数返回其参数的红利。如果定义函数会引发ZeroDivisionError异常,请打印解释性消息。“不会引发异常。你知道吗

我怀疑需要的是:

“定义一个函数,该函数试图返回其参数的红利。如果除法引发ZeriDivisionError异常,则函数将打印解释性消息并返回None。”因此def应该围绕整个函数的逻辑:

def di(a, b):
    try:
        return a/b
    except ZeroDivisionError:
        print "Divide by 0 error"

作为程序设计的一个更一般的观点,这样的函数有点耦合性差。除非受到其他因素的限制,否则Python程序员可能会得出这样的结论:让异常不被捕获比较简单:想必调用方当前必须测试None以确定是否发生了异常,那么为什么不在需要处理异常的任何地方捕获异常,并在那里处理它呢?你知道吗

通过返回不同类型的对象来指示数据的无效性会导致代码复杂且难以读取,从长远来看最好避免这种情况。不过,这对于学习活动来说是完全可以接受的!你知道吗

相关问题 更多 >