Python文件对象是真实的文件吗?

Python文件对象是真实的文件吗?,python,file-io,Python,File Io,在Python中,文件对象可能指向真实的文件、stdin、stdout、stderr,甚至其他东西。因此,它可以是类似于的文件,也可以是上所述的真实文件 如何知道文件是否为真实文件?我找到了一些猜测的方法,但似乎没有一种方法是可靠的: 文件不在[sys.stdin,sys.stdout,sys.stderr]中——似乎是最安全的,但仅适用于那些标准类型,而不是非常通用的解决方案 os.path.isfile(file.name)——看起来很安全,但如果在某些创建模式下打开新文件,可能无法工作 f

在Python中,文件对象可能指向真实的文件、stdin、stdout、stderr,甚至其他东西。因此,它可以是类似于的文件,也可以是上所述的真实文件

如何知道文件是否为真实文件?我找到了一些猜测的方法,但似乎没有一种方法是可靠的:

  • 文件不在[sys.stdin,sys.stdout,sys.stderr]
    中——似乎是最安全的,但仅适用于那些标准类型,而不是非常通用的解决方案
  • os.path.isfile(file.name)
    ——看起来很安全,但如果在某些创建模式下打开新文件,可能无法工作
  • file.fileno()==0
    ——假设该方法未实现,默认实现返回0,而正常实现从不返回0

  • file.name.startswith(“通常,您应该对称地使用
    with…as f:
    ,也就是说,使用
    with
    语句中打开或获取的文件句柄


    在UNIX上,您可以选中
    .fileno()
    -0表示标准输入,1表示标准输出,2表示标准错误;通常不应该关闭这些流,因为实际上已经没有办法再重新打开它们了


    file.name
    并不是100%可靠的方法,因为许多流可能有一个名称,即使它们不是真实的文件,并且该特殊名称可能与磁盘上的现有文件冲突:

    >>> import os.path
    >>> os.path.exists(sys.stdin.name)
    True
    >>> sys.stdin.name
    '<stdin>'
    
    S_ISREG
    如果模式描述普通文件,则返回
    True
    (此处输出到终端,因此为False);同样,您也可以通过
    isatty
    查找是否将任何文件重定向到终端:

    >>> os.isatty(sys.stdout.fileno())
    True
    
    来自Python的套接字库可能会有所帮助(其中
    file
    是一个文件对象):


    这是相当棘手的,因为可以编写一个通过所有测试的类似文件的对象类,但实际上仍然没有指向真实的文件。例如,My
    FakeFile
    类可以有一个指向现有文件的
    name
    属性,它可以覆盖
    fileno
    以返回0,等等。它似乎是一个足够确定的属性coder可以挫败你的每一次尝试。无论如何,你对
    的使用对我来说似乎很奇怪。大多数时候,我看到它像
    和open(filename)一样使用作为f:
    ,这消除了
    f
    可能指向stdin/out/err的可能性。您的第一句话是正确的,但例如
    argparse
    会直接给您一个打开的文件指针。
    >>> os.isatty(sys.stdout.fileno())
    True
    
        try:
            fileno = file.fileno()
        except (AttributeError, io.UnsupportedOperation) as err:
            raise _GiveupOnSendfile(err)  # not a regular file
        try:
            fsize = os.fstat(fileno).st_size
        except OSError as err:
            raise _GiveupOnSendfile(err)  # not a regular file