尝试在 class 中引发自定义异常

Trying to raise a custom exception within a class

class RadiusInputError(Exception):
    pass


class Circle:
    try:
        def __init__(self, radius):
            if isinstance(radius, int):
                pass
            else:
                raise RadiusInputError
            self.radius = radius
    except RadiusInputError:
        print('Radius is not a number')


c1 = Circle('hello')

当非整数值作为半径传递时,代码应该执行 except 块,但它显示以下错误:

Traceback (most recent call last):
  File "D:/Pycharm Projects/HelloWorld/HandsOn10.py", line 17, in <module>
    c1 = Circle('hello')
  File "D:/Pycharm Projects/HelloWorld/HandsOn10.py", line 11, in __init__
    raise RadiusInputError
__main__.RadiusInputError

问题是 try/except 块将恰好执行一次 - 在此 class 的定义处:

class Circle:
    try:
        # try to define this method
        def __init__(self, radius):
            if isinstance(radius, int):
                pass
            else:
                raise RadiusInputError
            self.radius = radius
        # if we got here, the method has been defined successfully!
    except RadiusInputError:
        # if we got here, an exception occurred WHILE DEFINING THE METHOD
        print('Radius is not a number')

此代码丝毫不会影响 Circle.__init__ 调用。

你可以在这里看到它是如何工作的:

>>> class Test:
...  print("before definition")
...  def __init__(self):
...    print("inside __self__")
...  print("after definition - bye!")
... 
before definition
after definition - bye!
>>> Test()
inside __self__
<__main__.Test object at 0x103541438>
>>> 

您必须在调用站点处理异常:

class Circle:
    def __init__(self, radius):
        if not isinstance(radius, int):
            raise RadiusInputError("Wrong radius!")
        self.radius = radius

try:
    c1 = Circle('hello')
except RadiusInputError as err:
    print(f"Oops, something went wring: {err}"!)

您将 __init__() 函数声明包装在 try/except 块中,但函数声明无法引发异常。

您应该考虑以下其中一项:

  1. __init__ 函数的内容包装在 try/except 中:
class Circle:
    def __init__(self, radius):
        try:
            if isinstance(radius, int):
                pass
            else:
                raise RadiusInputError
            self.radius = radius
        except RadiusInputError:
            print('Radius is not a number')


  1. 包装对象的初始化:
class Circle:
    def __init__(self, radius):
        if isinstance(radius, int):
            pass
        else:
            raise RadiusInputError
        self.radius = radius


try:
    c1 = Circle('hello')
except RadiusInputError:
    print('Radius is not a number')