【问题标题】:AttributeError in calling user-defined Python exception调用用户定义的 Python 异常时出现 AttributeError
【发布时间】:2015-09-07 16:06:42
【问题描述】:

我正在尝试主要从Python's documentation 进行异常处理。我遇到了一个奇怪的问题:目录包含main.pyexceptions.py

exceptions.py(没有导入语句)我定义我的异常类如下:

class ConvergenceError(AssertionError):
    def __init__(self,dc_places):
        self.decimal_places = dc_places
    def __str__(self):
        return 'convergence of R_inf is not correct to ', self.decimal_places

main.py 我有这个导入声明:

import exceptions as ex

我将异常称为如下:

try:
    np.testing.assert_array_almost_equal(R_inf,R_itr,4)
    raise ex.ConvergenceError(4) 
except ex.ConvergenceError as ce :  
    print str(ce)

我收到以下错误:

    except ex.ConvergenceError as ce :  
AttributeError: 'module' object has no attribute 'ConvergenceError'

我不明白为什么解释器在exceptions.py 模块中看不到Convergence

【问题讨论】:

  • print ex.__file__ 是否给出了您期望的结果?目录中有exceptions.pyc文件吗?
  • 我不知道 ex.__file__ 做了什么,但是当我运行它时没有任何改变。而且我的目录中没有 exceptions.pyc 文件
  • 如果您按照我的建议print ex.__file__,它将显示ex 所指的文件,这可能不是您所期望的。您也可以尝试print dir(ex) 查看该模块中定义了哪些属性
  • print dir(ex) 给了我:['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning'..] 对不起不习惯stackoverflow的格式
  • 那么您并没有导入您认为的模块。尝试使用您的自定义异常命名文件(例如custom_exceptions.py)并从中导入。

标签: python python-2.7 exception-handling


【解决方案1】:

正如您与jonrsharpe 讨论的那样,您的问题是您实际上正在导入一个内置模块exceptions。请尝试以下操作:

>>> import exceptions
>>> exceptions
<module 'exceptions' (built-in)>

所以你可以做的就是简单地重命名你的模块(例如到ex.py),你会很好:

>>> import ex
...

【讨论】:

    【解决方案2】:

    我想详细说明异常实际上是 C 内置的,并在解释器启动时加载(这仅适用于 Python2 而不是 Python3,对于 Python3,它在 builtins 中找到):

     >>> import sys
     >>> [i for i in sys.modules if 'exceptions' in i]
     ['exceptions']
     >>> import exceptions   # dictionary lookup to builtin
     <module 'exceptions' (built-in)>
    

    异常没有路径,并且出于相当明显的原因自动位于当前路径中:核心库中的解释器本身需要异常处理。这意味着如果您尝试通过任何标准方法导入异常,您将导入内置模块,而不是您想要的自定义模块。

    例如,这里我在路径中有 exceptions.py,并尝试通过标准导入加载它。

    >>> [i for i in os.listdir(os.getcwd()) if 'except' in i]
    ['exceptions.py']
    >>> import exceptions
    <module 'exceptions' (built-in)>
    exceptions = __import__("exceptions")
    >>> exceptions
    <module 'exceptions' (built-in)>
    

    你甚至不能重新加载它来强制它进入解释器。

    >>> reload(exceptions)
    <module 'exceptions' (built-in)>
    

    如果你使用 IMP 和自定义完整路径,你绝对可以强制它。

    >>> imp.load_source('exceptions', os.path.join(os.getcwd(), 'exceptions.py'))
    <module 'exceptions' from '/home/alex/exceptions.py'>
    

    编辑:我还应该提到,除了当前命名空间之外,这不会覆盖内置异常类。即使在异常名称被覆盖后,执行 from module import package 仍然引用内置函数。 Python 明智地不会让你在脚下开枪。

    >>> exceptions
    <module 'exceptions' from '/home/alex/exceptions.pyc'>
    >>> from exceptions import BaseException
    >>> BaseException
    <type 'exceptions.BaseException'>
    

    【讨论】:

      猜你喜欢
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      相关资源
      最近更新 更多