【问题标题】:Getting exception details in Python在 Python 中获取异常详细信息
【发布时间】:2025-12-18 02:20:04
【问题描述】:

我必须在同一个循环中打开并写入大约 10 个不同的文件。 例如:

for i in range(0,10):
    try:
        a=5
        file1 = open("file1.txt",'w+')
        file2 = open("file2.txt",'w+')
        #... etc

        print(str(a),file=file1)
        print(str(a)+"hi",file=file2)
        # ... etc
    except: 
        #error handling

现在我想做的是能够获取特定的异常信息,例如在一般异常中打开/写入的文件。根据我目前的理解,我必须做这样的事情来实现我想要的:

for i in range(0,5):
    a=5
    try:
        file1 = open("file1.txt",'w+')
        print(str(a),file=file1)
    except: 
        #error handling for file1
    try:
        file2 = open("file2.txt",'w+')
        print(str(a)+"hi",file=file2)
    except: 
        #error handling for file2

...当我必须为大约 10 个不同的文件执行此操作时,这将变得非常笨重且没有吸引力。有没有办法从我的第一个示例中的一般异常中获取(例如)文件名信息?基本上,因此异常可以报告诸如“写入 file1 时出错”之类的内容,而无需尝试/除了 file1 操作。

edit:这是对写入文件的数据的过度简化。 str(a) 和 str(a)+"hi" 并不能很好地表示实际写入的数据; file1 可能需要一个硬编码的整数,而 file2 可能需要一个用多个变量格式化的字符串。将打开/写入过程概括为一个循环不会很好地工作。

【问题讨论】:

    标签: python exception error-handling python-3.3


    【解决方案1】:

    您可以使用sys.exc_info 获取有关当前正在处理的异常的信息,包括异常对象本身。 IOError 异常包含您需要的所有信息,包括文件名、errno 和描述错误的字符串:

    import sys
    
    try:
        f1 = open('example1')
        f2 = open('example2')
    except IOError:
        type, value, traceback = sys.exc_info()
        print('Error opening %s: %s' % (value.filename, value.strerror))
    

    try 块中的执行显然在第一个异常之后仍会停止。

    【讨论】:

    • 不适用于 Python 2?
    • @GyuHyeonChoi 你看了吗?
    • 你没有提到版本。
    【解决方案2】:

    使用traceback 模块:

    traceback.print_exc()
    

    【讨论】:

    【解决方案3】:

    您提到使用循环,但实际上并没有使用循环。使用循环。这样您就可以在单个 try 块中写入每个文件,一次一个。除了向每个文件写入一个值外,您似乎没有对文件执行任何操作,因此您无需将它们全部打开。

    for filename in ['file1.txt', 'file2.txt', ...]:
        try:
            with open(filename, 'w+') as f:
                f.write(str(a)+"whatever")
        except IOError:
            print("Error occurred with", filename)
    

    编辑:如果您要向不同的文件写入完全不同的内容,请提前创建字典或其他数据结构来存储文件和数据之间的映射,然后在循环中使用它。

    data = {'file1.txt': str(a), 'file2.txt': 'something else', 'file3.txt': str(a)+str(b)}
    
    for filename, output in data.items():
        try:
            with open(filename, 'w+') as f:
                f.write(output)
        except IOError:
            print("Error occurred with", filename)
    

    【讨论】:

    • 我的意思是将包含的代码视为已经在循环中。生病解决。但无论如何,这并不能真正解决我的问题。写入这些文件的内容在任何方式、形状或形式上都不一定相似。 file1 可能需要打印一个硬编码的“1”,file2 可能需要打印一个变量,而 file3 可能需要多个变量。最终会发生的是“with”中的一个巨大的if语句;例如“如果文件名=文件1,写这个;如果文件名=文件2,写那个;如果文件名=文件3,写这个其他的东西”。代码会很笨重
    • @user891876:查看我编辑的答案。预先安排好文件和数据之间的关系,然后在循环中将每条数据写入其关联的文件中。
    • 如果 length(str(a)+str(b))>5 我不想打印到 file3 怎么办?每个文件肯定需要自己的逻辑。
    • @user891876:然后,在预计算中,在这种情况下将空字符串作为file3 的值。或者,您可以在循环中包含一个简单的检查,以检查“不要写入”值,例如 None,并将 None 放入预先计算的值中。关键是您可以在开始打开任何文件之前决定要写入每个文件的内容。
    • @user891876:更一般地说,决定如何处理每个文件的逻辑越复杂,您就越不能避免“笨拙”的代码。如果您尝试对 10 个文件执行 10 组完全不同的复杂操作,那不是一个操作,而是 10 个操作,您不能指望能够一次完成所有操作。但是,您应该尽可能在打开文件之前完成笨重的部分,因为这将有助于将创建数据时的逻辑错误(在您的控制之下)与写入数据时的 I/O 错误(可能不受你控制)。
    【解决方案4】:

    使用exc_type, value, exc_traceback = sys.exc_info()时,注意产生异常的文件名可以通过以下方式获取:

    exc_traceback.tb_frame.f_locals.get('filename')
    

    【讨论】: