如果我想冒泡一般的异常,我在python中做什么?

bha*_*ral 5 python exception

所以,假设我有这个python代码:

def loopForEachFileInDirectory(self, conn):
    for filename in os.listdir(uploadedFilesDirectory):
        try:
            self.insertNewEntryForStagingFile(conn, filename)
            self.copyFilesToStagingDirectory(filename)
        except: ???

def copyFilesToStagingDirectory(self, filename):
    logging.info("copying %s to youtube_ready",filename)
    try:
        shutil.copy(uploadedFilesDirectory+filename, stagingDirectory)
        logging.info("move successful")
    except shutil.Error,e:
        logging.warn("move failed for reasons \n\t%d:%s", e.args[0],e.args[1])
        raise ???
Run Code Online (Sandbox Code Playgroud)

现在,"loopForEachFileInDirectory"方法将会有更多的方法 - 我在这里做了一些干净的编码(欢呼Robert Martin).我想要的是从子方法中冒出任何异常,如果在主循环中发生任何事情,请在该循环上保释并继续.

问题是,冒泡一般异常的规则是什么?我只是自己筹集资金吗?如果是这样,我如何一般地抛出一个异常,我如何捕获并记录一般异常的细节?

mva*_*een 9

冒泡一般异常的规则是什么?我只是自己筹集资金吗?

是.简短的回答就是使用raise.

如果是这样,我如何一般地抛出异常......

上面回答的其他提交者发布的内容是正确的,但它没有提供太多的上下文方式.

Exception是基类异常. except Exception适用于所有类型, Exception因为所有Python异常都从此类继承.

except 语句可以指定指向异常对象的参数.

在这种情况下,我不认为指定它是绝对必要的.实际上,使用默认值冒出异常可能就足够了:

except:
  raise
Run Code Online (Sandbox Code Playgroud)

没有任何实际需要指定异常类型或e引用特定异常对象的变量.

..我如何捕获并记录一般异常的详细信息?

logging.exception是一个很好的方式去.试试吧:

try:
   <something that raises an error>
except Exception, e:
   logging.exception(e)
Run Code Online (Sandbox Code Playgroud)


Raf*_*ird 6

其他海报所写内容的简短 Python 3 扩展。大多数情况下,裸raise就足够了。它重新引发了原始异常,这是您在大多数情况下想要做的。

但是在某些情况下,您想要引发新的异常 - 也许是向原始异常添加更多信息(例如正在处理的罪魁祸首对象的 id),或者为了调用者的方便而将多个异常类型包装为一种。

在这种情况下raise ... from ...(恐怕只有 Python 3)构造很有用,例如:

try:
    self.file = open(filename)
except IOError, exc:
    raise DatabaseError('failed to open') from exc
Run Code Online (Sandbox Code Playgroud)

from子句的好处是它保留了原始异常的堆栈跟踪,如果您刚刚引发了一个全新的异常,它将丢失。

在 Python 2 中正确重新打包异常更难,Ian Bicking 有一篇很好的博客文章,涵盖了这个主题:http ://blog.ianbicking.org/2007/09/12/re-rising-exceptions/