【问题标题】:Why no len(file) in Python?为什么 Python 中没有 len(file)?
【发布时间】:2013-05-27 18:04:57
【问题描述】:

我对 Python 并不完全陌生,但我仍然无法理解是什么使某些东西“Pythonic”(反之亦然)。

如果这是一个愚蠢的问题,请原谅我,但为什么我不能通过执行 len(file) 来获得文件的大小?

file.__len__ 甚至没有实现,所以它不像其他东西需要它?如果它被实现为返回文件大小,是否会因某种原因而令人困惑/不一致?

【问题讨论】:

  • (1) 在python交互式解释器中执行import this。 (2) 因为要实现这一点,您需要将文件读完。所以,你最好让操作系统为你做这件事(例如this SO question
  • 因为有人想出了os.stat和statinfo.st_size

标签: python


【解决方案1】:

file 是一个迭代器。要查找行数,您需要阅读整个文件

sum(1 for line in file)

如果您想要文件中的字节数,请使用os.stat

例如

import os
os.stat(filename).st_size

【讨论】:

  • 好的,迭代器是有道理的。我想为一个文件实现__len__,它必须将文件读入内存,然后在缓冲区上执行 len() 。可能不是一个好主意。因此,您可以询问已经知道文件大小的操作系统,即 os.stat。谢谢!
【解决方案2】:

文件的定义比您想象的要广泛,尤其是在 Unix 中。例如,打印机的长度是多少?还是光驱?两者都是 /dev 中的文件,有点像 Windows。

对于我们通常认为的文件,它的长度是多少?变量的大小?文件的大小(以字节为单位)?后者更有意义,但随后变得更加棘手。应该列出文件内容的大小,还是它在磁盘上的大小(模数分配单元大小)。稀疏文件(具有不占用空间的大空白部分的文件,但属于文件通常报告的大小的一部分,受 NTFS 和 XFS 等文件系统支持)再次出现问题。

当然,所有这些问题的答案都可能是“只需选择一个并记录您选择的内容”。也许这正是应该做的,但要成为 Pythonic,通常必须明确一些东西,而不必阅读大量文档。 len(string) 很明显(可能有人会问返回值是字节还是字符),len(array) 很明显,len(file) 可能还不够。

【讨论】:

  • 值得注意的是,在 Python 3 中,str(代码点序列)和 bytes(字节序列)与 unicode/str 的区别相比有很大的区别在 Python 2 中,如何为每个定义 __len__ 更加清晰。
  • 谢谢,这是一个很好的答案。我只是将解决方案提供给@gnibbler,因为他是第一个指出__len__ 不能很好地处理文件的技术原因。
【解决方案3】:

file 返回一个迭代器,所以你不能在上面使用len()

要获取文件的大小,您可以使用os.stat

>>> foo = os.stat("abc")
>>> foo.st_size
193L

如果按大小表示行数,请尝试以下操作:

len(open("abc").readlines())

sum (1 for _ in open("abc"))

【讨论】:

  • 对于 Python 3 学习者来说,“193L”并不意味着“193 行”,它曾经意味着“193 是一个很大的数字”。
  • 我认为 L 代表“长”
【解决方案4】:

如果这是一个愚蠢的问题,请原谅我,但为什么我不能得到 通过执行 len(file) 来获得文件的大小?

Charles Burns 的回答很好地说明了 Unix 的“一切都是文件”哲学,尽管您始终可以使用 os.fstat() 来获取任何文件描述符的“大小”,例如...

import os

f = open(anything)
size = os.fstat(f.fileno()).st_size

...它可能不会返回任何有意义或有用的东西...

>>> os.fstat(sys.stdout.fileno()).st_size
0
>>> fd1, fd2 = os.pipe()
>>> os.fstat(fd1).st_size
0

我认为原因是 Python 文件对象或类似文件的对象应该表示一个流,而流本身没有长度,特别是如果它们是只写的,例如 sys.stdout .

通常,您可以保证的关于 Python 类文件对象的唯一事情是它将至少支持 read()write() 之一,仅此而已。

【讨论】:

    【解决方案5】:

    测量字符数的简单方法是:

    file = open('file.bin', 'r')
    # Seek to the end. (0 bytes relative to the end)
    file.seek(0, 2)
    length = file.tell()
    

    【讨论】:

    【解决方案6】:

    我会说,因为找到长度取决于操作系统特定的功能。您可以使用以下代码找到文件的长度:

    import os os.path.getsize('C:\\file.txt')

    您还可以将整个文件读入一个字符串并找出该字符串的长度。但是,您需要确保该文件不会太大而占用您的所有内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-04
      • 2013-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      相关资源
      最近更新 更多