38

バイトを kb から mb から gb から tb に変換するアプリケーションを作成しようとしています。これが私がこれまでに持っているものです:

def size_format(b):
    if b < 1000:
              return '%i' % b + 'B'
    elif 1000 <= b < 1000000:
        return '%.1f' % float(b/1000) + 'KB'
    elif 1000000 <= b < 1000000000:
        return '%.1f' % float(b/1000000) + 'MB'
    elif 1000000000 <= b < 1000000000000:
        return '%.1f' % float(b/1000000000) + 'GB'
    elif 1000000000000 <= b:
        return '%.1f' % float(b/1000000000000) + 'TB'

問題は、アプリケーションを試してみると、小数点以下がゼロになった後にすべてが得られることです。例 size_format(623)は「623B」を生成しますが、size_format(6200)「6.2kb」を取得する代わりに「6.0kb」を取得しています。理由はありますか?

4

18 に答える 18

3

コードを変更するのではなく、除算の動作を変更できます。

from __future__ import division

これにより、Python 2.x が使用する「クラシック」スタイルに対する「真の」分割が提供されます。詳細はPEP 238 - 除算演算子の変更を参照してください。

これが Python 3.x のデフォルトの動作になりました。

于 2012-09-21T03:03:31.053 に答える
1

値を除算するときは、両方の値が整数であるため、整数除算を使用しています。まず、そのうちの 1 つを float に変換する必要があります。

return '%.1f' % float(b)/1000 + 'KB'

または単に

return '%.1f' % b/1000.0 + 'KB'
于 2012-09-21T02:56:49.190 に答える
1

便利なDataSizeパッケージが追加されました:

pip install datasize
import datasize
import sys

a = [i for i in range(1000000)]
s = sys.getsizeof(a)
print(f"{datasize.DataSize(s):MiB}")

出力:

8.2945556640625MiB

于 2021-04-23T10:11:43.023 に答える
1

これは短くて簡潔だと思います。このアイデアは、私が何年も前に書いたグラフ スケーリング コードに基づいています。コード スニペットround(log2(size)*4)/40はここで魔法のように機能し、2**10 の累乗で増分して境界を計算します。「正しい」実装は次のようになります:trunc(log2(size)/10ただし、サイズが新しい境界に近づくと、奇妙な動作が発生します。たとえばdatasize(2**20-1)、(1024.00, 'KiB') が返されます。結果を使用roundしてスケーリングするlog2ことにより、新しい境界に近づいたときに適切なカットオフが得られます。

from math import log2
def datasize(size):
    """
    Calculate the size of a code in B/KB/MB.../
    Return a tuple of (value, unit)
    """
    assert size>0, "Size must be a positive number"
    units = ("B", "KiB", "MiB", "GiB", "TiB", "PiB",  "EiB", "ZiB", "YiB") 
    scaling = round(log2(size)*4)//40
    scaling = min(len(units)-1, scaling)
    return  size/(2**(10*scaling)), units[scaling]

for size in [2**10-1, 2**10-10, 2**10-100, 2**20-10000, 2**20-2**18, 2**20, 2**82-2**72, 2**80-2**76]:
    print(size, "bytes= %.3f %s" % datasize(size))

1023 bytes= 0.999 KiB
1014 bytes= 0.990 KiB
924 bytes= 924.000 B
1038576 bytes= 0.990 MiB
786432 bytes= 768.000 KiB
1048576 bytes= 1.000 MiB
4830980911975647053611008 bytes= 3.996 YiB
1133367955888714851287040 bytes= 0.938 YiB
于 2020-12-02T10:29:37.650 に答える
1

if...elseこれは、 Pythonであまり使用せずに、B (バイト) を MB、GB などの任意の高次に変換するコンパクト バージョンです。私はこれに対処するためにビット単位を使用します。return_outputまた、関数内のパラメーターを True としてトリガーすると、float 出力を返すこともできます。

import math

def bytes_conversion(number, return_float=False):

    def _conversion(number, return_float=False):

        length_number = int(math.log10(number))

        if return_float:

           length_number = int(math.log10(number))
           return length_number // 3, '%.2f' % (int(number)/(1 << (length_number//3) *10))

        return length_number // 3, int(number) >> (length_number//3) * 10

    unit_dict = {
        0: "B",  1: "kB",
        2: "MB", 3: "GB",
        4: "TB", 5: "PB",
        6: "EB"
    }

    if return_float:

        num_length, number = _conversion(number, return_float=return_float)

    else:
        num_length, number = _conversion(number)

    return "%s %s" % (number, unit_dict[num_length])

#Example usage:
#print(bytes_conversion(491266116, return_float=True))

これは、StackOverflow での私の投稿のほんの一部です。エラーや違反がある場合はお知らせください。

于 2018-08-20T04:40:07.763 に答える
0

除算を行う前に float(b) を実行します。たとえば、の代わりfloat(b)/1000に実行します。float(b/1000)bb/1000

于 2012-09-21T02:55:27.887 に答える