这是我需要移植的python2代码:
try:
  do_something_with_file(filename)
except:
  exc_type, exc_inst, tb = sys.exc_info()
  exc_inst.filename = filename
  raise exc_type, exc_inst, tb
使用上面的代码,我可以通过检查异常是否具有'filename'属性来获取有问题的输入文件的整个异常.
但是python3的加注已经改变了.这是2to3给我的上述代码:
except Exception as e:
  et, ei, tb = sys.exc_info()
  e.filename = filename
  raise et(e).with_traceback(tb)
这给了我另一个错误,我不认为文件名属性被保留:
in __call__
    raise et(e).with_traceback(tb)
TypeError: function takes exactly 5 arguments (1 given)
我只想要透明地传递异常和一些信息来跟踪输入文件.我想念python2 raise [exception_type[,exception_instance[,traceback]]]- 我怎么能在python3中做到这一点?
您可以设置__traceback__属性:
except Exception as e:
    et, ei, tb = sys.exc_info()
    ei.filename = filename
    ei.__traceback__ = tb
    raise ei
或者.with_traceback()直接在旧实例上调用:
except Exception as e:
    et, ei, tb = sys.exc_info()
    ei.filename = filename
    raise ei.with_traceback(tb)
但是,回溯已经自动附加,没有必要重新附加它,真的.
请参阅raise声明文档:
通常会在引发异常时自动创建回溯对象,并将其作为
__traceback__属性附加到该属性,该属性是可写的.
在这个特定的情况下,也许您想要一个不同的异常,而不是上下文?
class FilenameException(Exception):
    filename = None
    def __init__(self, filename):
        super().__init__(filename)
        self.filename = filename
try:
    something(filename)
except Exception as e:
    raise FilenameException(filename) from e
这将创建一个链式异常,如果未捕获则会打印两个异常,并且原始异常可用newexception.__context__.
您无需执行任何操作;在Python 3中,重新引发的异常会自动从原始引发的位置进行完整的追溯。
try:
  do_something_with_file(filename)
except Exception as exc_inst:
  exc_inst.filename = filename
  raise exc_inst
之所以起作用,是因为在捕获语句中的异常时适当地PyErr_NormalizeException设置了__traceback__属性except;参见http://www.python.org/dev/peps/pep-3134/。
| 归档时间: | 
 | 
| 查看次数: | 5105 次 | 
| 最近记录: |