try: except: 不起作用

10 投票
3 回答
8547 浏览
提问于 2025-04-16 11:33

我遇到了一个问题,发现 Python 中的 try: except: 机制似乎没有正常工作。

以下是我两个文件的内容。

pytest1.py

import pytest2

class MyError( Exception ):
    def __init__( self, value ):
        self.value = value

    def __str__( self ):
        return repr( self.value )

def func1():
    raise MyError( 'This is an error' )

def func3():
    pytest2.func2()

if __name__ == '__main__':
    try:
        func3()
    except MyError, e:
        print 'I should catch here.'
    except:
        print 'Why caught here?'

pytest2.py

from pytest1 import func1

def func2():
    func1()

运行第一个文件时,输出结果如下:

$ python pytest1.py
Why caught here?

基本上,异常没有被捕获。如果我打印出异常的类型,它显示为 <pytest1.MyError>,而不是简单的 <MyError>。我想这可能是某种奇怪的循环引用问题,但看起来应该是可以正常工作的。

3 个回答

1

... 我猜你的代码可能有命名空间的问题,这导致了不同的错误。

试着把

except:
    print 'Why caught here?'

换成

except Exception, e:
    print e

这样可能会让你更清楚出错的原因。

2

这个问题是因为你把正在运行的脚本当作模块导入了。这样会导致模块有两个独立的副本!

再举个例子:

module.py

import module

class Foo: pass

def test():
    print Foo
    print module.Foo
    print Foo is module.Foo

if __name__ == '__main__': test()

main_script.py

import module
if __name__ == '__main__': module.test()

结果

>python main_script.py
module.Foo
module.Foo
True

>python module.py
__main__.Foo
module.Foo
False

运行 python somefile.py 会创建一个叫 __main__ 的模块,而不是 somefile,并在这个模块中运行 somefile.py 的代码。这就是为什么我们使用 if __name__ == '__main__': 来检查这个文件是作为脚本运行还是从其他文件导入的原因。

9

在Python中,主程序总是以一个叫做 __main__ 的模块被导入。

当你导入 pytest2 时,它不会重复使用已经存在的模块,因为最开始导入的模块名字是 __main__,而不是 pytest2。这样一来,pytest1 就会被运行多次,导致出现多个异常类。比如说 __main__.MyErrorpytest1.MyError。最后你可能会抛出一个错误,却试图捕捉另一个错误。

所以,不要试图从其他模块导入你的主模块。

撰写回答