在Python中更好的文件大小转换方式

152 投票
12 回答
248022 浏览
提问于 2025-04-16 13:00

我正在使用一个库,它可以读取一个文件并返回这个文件的大小,单位是字节。

然后,我把这个文件的大小显示给用户。为了让用户更容易理解,我会把文件大小转换成 MB(兆字节),方法是用文件大小除以 1024.0 * 1024.0。这样做当然没问题,但我在想,Python里有没有更好的方法来做到这一点呢?

我说的更好,是指有没有一个标准库的函数,可以根据我想要的类型来处理文件大小。比如说,如果我指定 MB,它就能自动帮我除以 1024.0 * 1024.0。类似这样的功能。

12 个回答

62

你可以用位移运算符 << 来代替直接用 1024 * 1024 来计算大小,比如用 1<<20 来得到兆字节(MB),用 1<<30 来得到千兆字节(GB)等等。

在最简单的情况下,你可以定义一个常量,比如 MBFACTOR = float(1<<20),然后用它来处理字节数,比如:megas = size_in_bytes/MBFACTOR

通常情况下,你只需要用到兆字节,或者你也可以用类似的方式:

# bytes pretty-printing
UNITS_MAPPING = [
    (1<<50, ' PB'),
    (1<<40, ' TB'),
    (1<<30, ' GB'),
    (1<<20, ' MB'),
    (1<<10, ' KB'),
    (1, (' byte', ' bytes')),
]


def pretty_size(bytes, units=UNITS_MAPPING):
    """Get human-readable file sizes.
    simplified version of https://pypi.python.org/pypi/hurry.filesize/
    """
    for factor, suffix in units:
        if bytes >= factor:
            break
    amount = int(bytes / factor)

    if isinstance(suffix, tuple):
        singular, multiple = suffix
        if amount == 1:
            suffix = singular
        else:
            suffix = multiple
    return str(amount) + suffix

print(pretty_size(1))
print(pretty_size(42))
print(pretty_size(4096))
print(pretty_size(238048577))
print(pretty_size(334073741824))
print(pretty_size(96995116277763))
print(pretty_size(3125899904842624))

## [Out] ###########################
1 byte
42 bytes
4 KB
227 MB
311 GB
88 TB
2 PB
264

这是我使用的内容:

import math

def convert_size(size_bytes):
   if size_bytes == 0:
       return "0B"
   size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
   i = int(math.floor(math.log(size_bytes, 1024)))
   p = math.pow(1024, i)
   s = round(size_bytes / p, 2)
   return "%s %s" % (s, size_name[i])

注意:大小应该以字节为单位发送。

150

有一个叫做 hurry.filesize 的工具,它可以把字节大小转换成好看的字符串。

>>> from hurry.filesize import size
>>> size(11000)
'10K'
>>> size(198283722)
'189M'

或者,如果你想要1K等于1000(这也是大多数用户的假设):

>>> from hurry.filesize import size, si
>>> size(11000, system=si)
'11K'
>>> size(198283722, system=si)
'198M'

它也支持IEC标准(不过这个没有详细说明):

>>> from hurry.filesize import size, iec
>>> size(11000, system=iec)
'10Ki'
>>> size(198283722, system=iec)
'189Mi'

因为这个工具是由非常棒的Martijn Faassen写的,所以代码简洁明了,还很容易扩展。自己写一个系统也非常简单。

下面是一个示例:

mysystem = [
    (1024 ** 5, ' Megamanys'),
    (1024 ** 4, ' Lotses'),
    (1024 ** 3, ' Tons'), 
    (1024 ** 2, ' Heaps'), 
    (1024 ** 1, ' Bunches'),
    (1024 ** 0, ' Thingies'),
    ]

使用方法如下:

>>> from hurry.filesize import size
>>> size(11000, system=mysystem)
'10 Bunches'
>>> size(198283722, system=mysystem)
'189 Heaps'

撰写回答