在python中,当不在正确的包中时未捕获异常

在python中,当不在正确的包中时未捕获异常,python,exception,package,Python,Exception,Package,编辑: 好的,我成功地隔离了这个bug以及复制它的准确、完整的代码。但它看起来要么是设计上的问题,要么是python中的错误 创建两个同级包:admin和General,当然,每个包都有自己的\uuuu init\uuuuuuuuuuuuy。 在包admin中,将带有以下代码的文件“test.py”放入其中: from General.test02 import run import RunStoppedException try: run() except RunStoppedExce

编辑: 好的,我成功地隔离了这个bug以及复制它的准确、完整的代码。但它看起来要么是设计上的问题,要么是python中的错误

创建两个同级包:
admin
General
,当然,每个包都有自己的
\uuuu init\uuuuuuuuuuuuy
。 在包
admin
中,将带有以下代码的文件“test.py”放入其中:

from General.test02 import run
import RunStoppedException
try:
    run()
except RunStoppedException.RunStoppedException,e:
    print 'right'
except Exception,e:
    print 'this is what i got: %s'%type(e)
class RunStoppedException(Exception):
    def __init__(self):
        Exception.__init__(self)
并且在
admin
中放入带有以下代码的文件“runstoppedeexception.py”:

from General.test02 import run
import RunStoppedException
try:
    run()
except RunStoppedException.RunStoppedException,e:
    print 'right'
except Exception,e:
    print 'this is what i got: %s'%type(e)
class RunStoppedException(Exception):
    def __init__(self):
        Exception.__init__(self)
在包
General
中,将文件test02.py与代码放在一起:

import admin.RunStoppedException
def run():
    raise admin.RunStoppedException.RunStoppedException()
打印输出:

this is what i got: <class 'admin.RunStoppedException.RunStoppedException'>
这就是我得到的:
当它应该是正确的时候。只有当一个文件与异常位于同一目录中时,才会发生这种情况,因此它们的导入方式不同

这是设计的,还是python的一个bug


我正在使用python2.6,在eclipse+pydev下运行它

我只能看到两个原因

  • 您有两个同名的不同异常类
    编辑:我认为罪魁祸首是这一部分,因为您通过两种方式导入异常类

    • 从RunStoppedException导入RunStoppedException
    • 从admin.RunStoppedException导入RunStoppedException
    让他们保持一致,你的问题就会消失

  • 您正在使用某个IDE,它会干扰您的代码,这听起来很奇怪,但如果您不这样做,请尝试在命令行上运行您的代码

  • 即使1和2也不能解决您的问题,请编写一小段代码来演示这个问题,我们可以在这里运行,我们可以解决,但我相信我们不需要这样做,因为一旦您编写了这样一个小的独立脚本,您可以在其中复制问题,您也会找到解决方案。

    对我来说很好:

    [/tmp] ls admin/
    RunStoppedException.py  __init__.py     test.py
    RunStoppedException.pyc __init__.pyc
    [/tmp] ls General/
    __init__.py __init__.pyc    test02.py   test02.pyc
    [/tmp] python -m admin.test 
    right
    [/tmp] 
    
    运行于:

    Python 2.6.4 Stackless 3.1b3 060516 (release26-maint, Dec 14 2009, 23:28:06) 
    [GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin
    
    我的猜测是,在您的路径上有另一个“常规”,可能来自早期的测试,这就是异常不匹配的原因。 您是否尝试了
    id
    /
    inspect.getabsfile
    调试?如果是,结果是什么

    import admin.RunStoppedException
    
    这是一个模棱两可的相对导入。您的意思是来自
    admin
    顶级模块的
    RunStoppedException
    ?或者在包中时从
    mypackage.admin
    ?如果您当前的工作目录(添加到模块搜索路径中)恰好在包内,那么它可能在包内,这取决于Python是否知道它在包内,这取决于您如何运行脚本

    如果您在不同的模块中同时拥有
    import admin.RunStoppedException
    import RunStoppedException
    ,那么很可能会导入同一模块的两个副本:包
    admin
    的顶级
    RunStoppedException
    和子模块
    admin.RunStoppedException
    ,导致两个异常实例,以及随后的
    异常中的不匹配

    所以不要使用隐式相对导入。他们无论如何都要离开(见)。始终拼写完整的模块名称,例如,
    import mypackage.admin.RunStoppedException
    。但是,请避免对模块名和类名使用相同的标识符,因为这会让人非常困惑。请注意,Python将允许您说:

    except RunStoppedException:
    
    其中,该标识符指的是一个模块,而不是Exception的子类。这是出于历史原因,也可能会消失,但同时它可以隐藏bug。一种常见的模式是使用
    mypackage.exceptions
    来保存许多异常。每个文件一个类是Python不赞成的Java习惯


    通常最好尽量减少模块内容(如类)的导入。如果模块中的
    RunStoppedException
    副本发生了更改,那么您现在将在不同的脚本中拥有不同的副本。虽然类基本上不会改变,但模块级变量可能会改变,当您将内容带到其所有者模块之外时,monkey修补和重新加载变得更加困难。

    也许您有两个名为RightException的类。您捕获的异常类型应该是“admin.RightException.RightException”,而不仅仅是“RightException”。@Mark-这是我的第一个猜测,但不是。我想可能是因为异常模块与异常本身具有相同的名称,所以我将其包括在本例中,但这并不重要@mikej-这是相同的代码,除了将异常的真实名称替换为“RightException”。除此之外-在名为admin/RightException.py的文件中定义了相同的代码RightException?这是导致问题的实际代码,还是仅仅是您为说明所做工作而编写的示例?第二个except行实际上是Exception,Exception:?什么版本的Python?我希望消息实际上是这样读的:“这是我得到的:”而不仅仅是“这是我得到的:RightException”
    %type(exception)
    应该是
    %type(e)
    。请发布一个生成您看到的行为的完整代码段。请努力创建一个自包含的代码段,然后复制并粘贴它,以及您得到的输出。看起来某个地方有一个很微妙的bug,所以任何一点遗漏都可能隐藏在视线之外。在我更改我的问题之前,你是否编写了你的答案,因为你现在可以自己运行代码:)它似乎有更深层次的东西,上面的两个检查无法解决…现在通过对您的示例的测试进行编辑我已更改代码以明确引用每个位置(参见上文)-仍然没有骰子。因此,我认为您的猜测是错误的,尽管我同意用相同的名称命名模块和类是不好的practice@bobince-谢谢!这看起来是对问题的正确诊断(将进一步深入研究),唯一的问题是,我不知道我在哪里进行“隐式”导入。我在清楚地拼写