4

编辑:好的,我设法隔离了错误和准确、完整的代码来重现它。但它看起来要么是设计的东西,要么是 python 中的错误。

创建两个兄弟包:admin& General,当然每个都有自己__init__.py的。在包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)

admin使用以下代码放入文件“RunStoppedException.py”:

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'>

应该是什么时候right。这只发生在一个文件与异常位于同一目录中时,因此它们以不同方式导入它。

这是设计使然,还是python的错误?

我用的是python2.6,在eclipse+pydev下运行

4

3 回答 3

7
import admin.RunStoppedException

这是一个模棱两可的相对导入。你的意思是RunStoppedExceptionadmin顶级模块?或者从mypackage.admin你在包裹里的时候开始?如果您当前的工作目录(添加到模块搜索路径)恰好在包内,则可能是其中一个,这取决于 Python 是否知道它在包内,这取决于您运行脚本的方式。

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

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

except RunStoppedException:

该标识符指的是模块而不是异常的子类。这是出于历史原因,也可能会消失,但同时它可以隐藏错误。一个常见的模式是mypackage.exceptions用来保存许多异常。每个文件一个类是一种在 Python 中不受欢迎的 Java 习惯。

通常尽量减少模块内容(如类)的导入也是一个好主意。如果RunStoppedException模块内部的副本发生了变化,您现在将在不同的脚本中拥有不同的副本。虽然类大多不会改变,但模块级变量可能会,当你在其所有者模块之外获取东西时,猴子修补和重新加载变得更加困难。

于 2010-01-01T13:53:32.447 回答
0

我只能看到两个原因

  1. 您有两个具有相同名称的不同异常类
    编辑:我认为罪魁祸首是这部分,因为您以两种方式导入异常类

    • 从 RunStoppedException 导入 RunStoppedException
    • 从 admin.RunStoppedException 导入 RunStoppedException

    使它们保持一致,您的问题就会消失。

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

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

于 2010-01-01T13:09:51.217 回答
0

对我来说很好:

[/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调试吗?如果是这样,输出是什么?

于 2010-01-01T13:45:11.873 回答