Searching for equivalent of FileNotFoundError in Python 2

前端 未结 4 671
鱼传尺愫
鱼传尺愫 2020-12-28 12:17

I created a class named Options. It works fine but not not with Python 2. And I want it to work on both Python 2 and 3. The problem is identified: FileNotFoundError doesn t

相关标签:
4条回答
  • 2020-12-28 12:49

    If FileNotFoundError isn't there, define it:

    try:
        FileNotFoundError
    except NameError:
        FileNotFoundError = IOError
    

    Now you can catch FileNotFoundError in Python 2 since it's really IOError.

    Be careful though, IOError has other meanings. In particular, any message should probably say "file could not be read" rather than "file not found."

    0 讨论(0)
  • 2020-12-28 13:05

    You can use the base class exception EnvironmentError and use the 'errno' attribute to figure out which exception was raised:

    from __future__ import print_function
    
    import os
    import errno
    
    try:
        open('no file of this name')   # generate 'file not found error'
    except EnvironmentError as e:      # OSError or IOError...
        print(os.strerror(e.errno))  
    

    Or just use IOError in the same way:

    try:
        open('/Users/test/Documents/test')   # will be a permission error
    except IOError as e:
        print(os.strerror(e.errno))  
    

    That works on Python 2 or Python 3.

    Be careful not to compare against number values directly, because they can be different on different platforms. Instead, use the named constants in Python's standard library errno module which will use the correct values for the run-time platform.

    0 讨论(0)
  • 2020-12-28 13:05

    The Python 2 / 3 compatible way to except a FileNotFoundError is this:

    import errno
    
    try:
        with open('some_file_that_does_not_exist', 'r'):
            pass
    except EnvironmentError as e:
        if e.errno != errno.ENOENT:
            raise
    

    Other answers are close, but don't re-raise if the error number doesn't match.

    Using IOError is fine for most cases, but for some reason os.listdir() and friends raise OSError instead on Python 2. Since IOError inherits from OSError it's fine to just always catch OSError and check the error number.

    Edit: The previous sentence is only true on Python 3. To be cross compatible, instead catch EnvironmentError and check the error number.

    0 讨论(0)
  • 2020-12-28 13:05

    For what it's worth, although the IOError is hardly mentioned in Python 3's official document and does not even showed up in its official Exception hierarchy, it is still there, and it is the parent class of FileNotFoundError in Python 3. See python3 -c "print(isinstance(FileNotFoundError(), IOError))" giving you a True. Therefore, you can technically write your code in this way, which works for both Python 2 and Python 3.

    try: 
        content = open("somefile.txt").read()
    except IOError:  # Works in both Python 2 & 3
        print("Oops, we can not read this file")
    

    It might be "good enough" in many cases. Although in general, it is not recommended to rely on an undocumented behavior. So, I'm not really suggesting this approach. I personally use Kindall's answer.

    0 讨论(0)
提交回复
热议问题