【问题标题】:Check if an object is a file in Python 2 and 3检查对象是否是 Python 2 和 3 中的文件
【发布时间】:2017-11-27 19:47:47
【问题描述】:

是否有兼容 Python 2/3 的方法来检查对象是否为文件?

我需要检查对象 filehandler 是否实际上是 file 对象。这段代码需要在 Python 2 和 3 中运行。在 Python 2 中我可以做到

isinstance(filehandler, file)

但是file is not part of Python 3,所以这段代码在使用 Python 3 运行时会引发 NameError

根据this answer,在Python 3 中io.IOBase 应该用于检查对象是否为文件,但Python 2 的file 没有子类io.IOBase,因此isinstance(filehandler, io.IOBase) 将不起作用。

我考虑过使用isinstance(filehandler, (io.IOBase, file)),但是当我使用 Python 3 运行它时,它仍然给出了NameError

有没有一种方法可以同时兼容 Python 2.7 和 3?

【问题讨论】:

    标签: python python-3.x python-2.7 compatibility


    【解决方案1】:

    我发现最常用的方法是在 Python 3 中检查 hasattr。因此,我添加了一个检查 Python 版本的检查,并根据它执行正确的功能。

    import sys
    
    def isFile(f):
        return isinstance(f,file) if sys.version_info[0] == 2 else hasattr(f, 'read')        
    
    f = open("post.php","r")
    print(isFile(f))
    print(isFile(10))
    

    或者,您可以使用lambda,但我觉得它的可读性较差。

    isFile = lambda f:isinstance(f,file) if sys.version_info[0] == 2 else hasattr(f, 'read')   
    

    【讨论】:

    • lambda 的意义在于它是一个未命名的函数,因此如果您需要一个命名函数,则没有理由不使用 def。更清晰,更易读
    【解决方案2】:

    这是我使用的解决方法:在.py 文件的顶部,我添加了:

    import sys
    
    if sys.version_info[0] == 3:
        from io import IOBase
        file = IOBase
    

    因此,如果使用的是 Python 3,请将 file 设置为 IOBase。现在isinstance(filehandler, file) 将在 Python 3 中正常工作,而对于 Python 2,它将像往常一样工作。

    当然,这个解决方案非常老套和令人困惑,因为它使IOBase 看起来像是file 的 Python 3 版本,但事实并非如此。但它确实解决了问题。

    【讨论】:

    • IOBase 不保证像对象这样的文件,例如>>> my_var = tempfile.NamedTemporaryFile() >>> my_var <tempfile._TemporaryFileWrapper object at 0x10206e198> >>> isinstance(z, io.IOBase) False
    【解决方案3】:

    为什么不做这样的事情

    try:
        #check in py3
    except:
        #check in py2
    

    如果需要,您可以添加一些其他错误处理程序,但应该这样做。

    【讨论】:

    • 我确定您的意思是 except NameError: 而不是毯子 except: 对吗?
    • 是的,如果你相对确定你会得到什么,那可能会更安全
    • 最好只捕捉你知道你会得到的东西,而不是试图捕捉所有东西。如果代码由于其他一些意想不到的原因抛出了ValueError,那么我想毯子except会导致难以调试的错误。
    • 这个代码块不起作用,因为使用 Py3 检查不会在 Py2 中引发错误,它只会给出错误的答案。 Py2和Py3代码需要切换
    猜你喜欢
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 2011-09-20
    • 2011-02-25
    • 2017-10-15
    • 2018-09-10
    相关资源
    最近更新 更多