Python库从字节计算人类可读的文件大小?

pyn*_*ice 13 python python-module

我发现hurry.filesize非常有用,但它不提供十进制输出?

例如:

print size(4026, system=alternative) gives 3 KB.
Run Code Online (Sandbox Code Playgroud)

但是后来当我添加所有值时,我没有得到确切的总和.例如,如果输出为hurry.filesize4变量且每个值为3.如果我将它们全部添加,则输出为15.

我正在寻找hurry.filesize的替代方案来获得小数输出.

nne*_*neo 41

这自己并不难实现:

suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
def humansize(nbytes):
    i = 0
    while nbytes >= 1024 and i < len(suffixes)-1:
        nbytes /= 1024.
        i += 1
    f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
    return '%s %s' % (f, suffixes[i])
Run Code Online (Sandbox Code Playgroud)

例子:

>>> humansize(131)
'131 B'
>>> humansize(1049)
'1.02 KB'
>>> humansize(58812)
'57.43 KB'
>>> humansize(68819826)
'65.63 MB'
>>> humansize(39756861649)
'37.03 GB'
>>> humansize(18754875155724)
'17.06 TB'
Run Code Online (Sandbox Code Playgroud)

  • ... [格式化很难](http://stackoverflow.com/questions/14997799/most-pythonic-way-to-print-at-most-some-number-of-decimal-places). (4认同)
  • 有点迂腐,但你可能想要使用KiB,MiB等...... (3认同)
  • 我碰巧严重不喜欢那些后缀.但是,由于代码非常清楚,如果你真的想要改变它应该不难;) (2认同)

Tim*_*awa 6

免责声明:我写了我要描述的包

模块bitmath支持您描述的功能.它还解决了@filmore的评论,在语义上我们应该使用NIST单元前缀(不是SI),也就是说,MiB而不是MB.现在也支持舍入.

你原来问的是:

print size(4026, system=alternative)
Run Code Online (Sandbox Code Playgroud)

bitmath中,默认前缀单元系统是NIST(基于1024),因此,假设您指的是4026 字节,则bitmath中的等效解决方案将类似于以下任何一种:

In [1]: import bitmath

In [2]: print bitmath.Byte(bytes=4026).best_prefix()
3.931640625KiB

In [3]: human_prefix = bitmath.Byte(bytes=4026).best_prefix()

In [4]: print human_prefix.format("{value:.2f} {unit}")
3.93 KiB
Run Code Online (Sandbox Code Playgroud)

我目前有一个开放的任务,允许用户在使用该best_prefix方法时选择首选前缀单元系统.

更新日期:2014年7月16日最新的包已经被上传到PyPI中,它包括了一些新的功能(全功能列表是在GitHub的页面)

  • 我知道一些开发人员认为这是一项“需要库的任务太小”,但我不同意,因为这会导致开发人员不断重新发明轮子。无论如何,这个图书馆正是我要找的!谢谢蒂姆! (2认同)

Lip*_*pis 5

这没有必要比@nneonneo解决方案快,如果我能说的话,它稍微一点:)

import math

suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']

def human_size(nbytes):
  human = nbytes
  rank = 0
  if nbytes != 0:
    rank = int((math.log10(nbytes)) / 3)
    rank = min(rank, len(suffixes) - 1)
    human = nbytes / (1024.0 ** rank)
  f = ('%.2f' % human).rstrip('0').rstrip('.')
  return '%s %s' % (f, suffixes[rank])
Run Code Online (Sandbox Code Playgroud)

这基于一个事实,即以10为任何数字的对数的整数部分比实际数字位数小1。其余的几乎是直截了当的。