简体   繁体   English

以独立于平台的方式处理特定于 Windows 的异常

[英]Handling Windows-specific exceptions in platform-independent way

Consider the following Python exception:考虑以下 Python 异常:

  [...]
    f.extractall()
  File "C:\Python26\lib\zipfile.py", line 935, in extractall
    self.extract(zipinfo, path, pwd)
  File "C:\Python26\lib\zipfile.py", line 923, in extract
    return self._extract_member(member, path, pwd)
  File "C:\Python26\lib\zipfile.py", line 957, in _extract_member
    os.makedirs(upperdirs)
  File "C:\Python26\lib\os.py", line 157, in makedirs
    mkdir(name, mode)
WindowsError: [Error 267] The directory name is invalid: 'C:\\HOME\\as\
\pypm-infinitude\\scratch\\b\\slut-0.9.0.zip.work\\slut-0.9\\aux'

I want to handle this particular exception - ie, WindowsError with error number 267. However, I cannot simply do the following:我想处理这个特殊的异常——即错误号为 267 的 WindowsError。但是,我不能简单地执行以下操作:

try:
    do()
except WindowsError, e:
    ...

Because that would not work on Unix systems where WindowsError is not even defined in the exceptions module.因为这在 Unix 系统上不起作用,其中 WindowsError 甚至没有在 exceptions 模块中定义。

Is there an elegant way to handle this error?有没有一种优雅的方法来处理这个错误?

If you need to catch an exception with a name that might not always exist, then create it:如果您需要捕获名称可能并不总是存在的异常,请创建它:

if not getattr(__builtins__, "WindowsError", None):
    class WindowsError(OSError): pass

try:
    do()
except WindowsError, e:
    print "error"

If you're on Windows, you'll use the real WindowsError class and catch the exception.如果您使用的是 Windows,您将使用真正的 WindowsError 类并捕获异常。 If you're not, you'll create a WindowsError class that will never be raised, so the except clause doesn't cause any errors, and the except clause will never be invoked.如果不是,您将创建一个永远不会引发的 WindowsError 类,因此 except 子句不会导致任何错误,并且永远不会调用 except 子句。

Here's my current solution, but I slightly despise using non-trivial code in a except block:这是我当前的解决方案,但我有点鄙视在 except 块中使用非平凡代码:

        try:
            f.extractall()
        except OSError, e:
            # http://bugs.python.org/issue6609
            if sys.platform.startswith('win'):
                if isinstance(e, WindowsError) and e.winerror == 267:
                    raise InvalidFile, ('uses Windows special name (%s)' % e)
            raise

@Glenn Maynard 's answer does not allow debugging with pdb as the WindowsError builtin is not available in the debugger. @Glenn Maynard 的回答不允许使用 pdb 进行调试,因为 WindowsError 内置在调试器中不可用。 This code block will work inside of the Python debugger and during normal execution:此代码块将在 Python 调试器内部和正常执行期间工作:

import exceptions

if not getattr(exceptions, "WindowsError", None):
        class WindowsError(OSError): pass

This solution also works and avoids string literals and an import of the full exceptions library:此解决方案也有效并避免字符串文字和完整异常库的导入:

try:
    from exceptions import WindowsError
except ImportError:
    class WindowsError(OSError): pass

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM