Python中的try/except语句无法正常工作

14
尝试让try/except语句工作,但遇到问题。此代码将获取一个txt文件并复制位于第0行位置的文件到第1行位置的位置。它可以正常工作,但是如果我将其中一个路径更改为无效路径,则会生成错误ftplib.error_perm,但except命令没有捕获到,一切都停止了。我做错了什么?Python 2.4
import csv
import operator
import sys
import os
import shutil
import logging
import ftplib
import tldftp

def docopy(filename):
        ftp = tldftp.dev()
        inf = csv.reader(open(filename,'r'))
        sortedlist = sorted(inf, key=operator.itemgetter(2), reverse=True)
        for row in sortedlist:
                src = row[0]
                dst = row[1]
                tldftp.textXfer(ftp, "RETR " + src, dst)


def hmm(haha):
    result = docopy(haha);
    try:
        it = iter(result)
    except ftplib.error_perm:
        print "Error Getting File" 


if __name__ == "__main__":
        c = sys.argv[1]
        if (c == ''):
                raise Exception, "missing first parameter - row"
        hmm(c)

3
附言:这是一些奇怪的缩进,这将导致问题。使用 python -tt your_program_name.py 运行您的代码以确认不一致的空格使用,然后在所有地方切换到 4 空格缩进。 - DSM
7个回答

11
except子句只能捕获在其对应的try块内部raise的异常。请尝试将docopy函数调用也放入try块中:
def hmm(haha):
    try:
        result = docopy(haha)
        it = iter(result)
    except ftplib.error_perm:
        print "Error Getting File" 

那导致它打印了“获取文件错误”,但是try命令不应该然后继续执行其余的结果吗? - user1943219
3
不,一旦try块中出现错误,try块中的代码执行就会停止,并且不会重新开始。 - Matt

4
代码中引发错误的点必须在try块内部。 在这种情况下,很可能是docopy函数引发了错误,但它没有被包含在try块中。
请注意,docopy返回None。 因此,当您尝试从None创建一个iter时,会引发异常 - 但它不会是ftplib.error_perm异常,而是TypeError

1

如果您不确定会发生什么异常,请使用以下代码,因为如果指定了例如:except StandardError:,而不是该错误,则不会处理异常。

try:
    # some code
except Exception: # Or only except:
   print "Error" # Python 3: print("Error")

0

我注意到全局异常可能无法正常工作,例如,在epub.py模块执行urllib3连接触发KeyboardInterrupt时,无法在主线程中捕获,解决方法是将我的清理代码放在finally中,例如:

try:
    main()
except Exception as e:
    clean_up_stuff()  #this one never called if keyboard interrupt in module urllib3 thread
finally: #but this work
    clean_up_stuff() 

0
我遇到了一个奇怪的特殊情况,导致了这个问题,可能值得分享一下。
我将一个自定义错误类重构到一个新的包中,代码中有一个地方抛出了这个错误,但是raise语句中的本地导入声明引用了旧的包。由于某种原因,异常在没有被except Exception:捕获的情况下被构造和抛出(当我无法弄清楚发生了什么时,我添加了这个检查作为一种合理性检查)。
当然,解决方案是在导入错误的地方修复包的名称。我猜测我的虚拟环境或缓存中可能存在旧的错误包和类,这就是为什么它能够成功导入和构造。然而,我非常惊讶我竟然无法完全捕获它,因为即使在旧的包中,它也继承自BaseException
注意:这发生在我使用Python 3.11运行时执行代码时。

0

我知道这个问题已经很古老了,但是对于那些迫切需要答案的人来说,我有一个类似的问题。根据你使用的IDE,如果你在特定异常等行上设置了断点,这可能会导致冲突并阻止try/except执行。


0

这个例子适用于Python3.3+,当装饰生成器函数时,装饰后的生成器会成功返回,因此不会进入装饰器中,神奇的事情发生在yield from f中,从而将可yield的内容包装在装饰器内:

from types import GeneratorType    

def generic_exception_catcher(some_kwarg: int = 3):
    def catch_errors(func):
        def func_wrapper(*args, **kwargs):
            try:
                f = func(*args, **kwargs)
                if type(f) == GeneratorType:
                    yield from f
                else:
                    return f
            except Exception as e:
                raise e
        return func_wrapper
    return catch_errors

使用方法:

@generic_exception_catcher(some_kwarg=4)
def test_gen():
    for x in range(0, 10):
        raise Exception('uhoh')
        yield x

for y in test_gen():
    print('should catch in the decorator')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接