调用用户定义的Python异常时的AttributeError

时间:2015-09-07 16:06:42

标签: python python-2.7 exception-handling

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

exceptions.py中(没有import语句)我定义了我的异常类,如下所示:

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'

我无法弄清楚为什么口译员在Convergence模块中看不到exceptions.py

2 个答案:

答案 0 :(得分:3)

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

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

所以你可以做的只是重命名你的模块(例如改为ex.py),你会很好:

>>> import ex
...

答案 1 :(得分:3)

我想详细说明异常实际上是一个C-builtin,并且在解释器的开头加载(这只适用于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'>