Bytes für Menschen lesbar und zurück. ohne Datenverlust

Ich muss Zeichenketten konvertieren, die die Speichernutzung in Bytes enthalten, wie:1048576 (das ist 1M) in genau das, eine für Menschen lesbare Version und umgekehrt.

Hinweis: Ich habe hier schon gesucht:Wiederverwendbare Bibliothek, um eine lesbare Version der Dateigröße zu erhalten?

Und hier (obwohl es nicht Python ist):Wie konvertiert man menschenlesbare Speichergröße in Bytes?

Bisher hat mir nichts geholfen, also habe ich woanders gesucht.

Ich habe hier etwas gefunden, das dies für mich erledigt:http://code.google.com/p/pyftpdlib/source/browse/trunk/test/bench.py?spec=svn984&r=984#137 oder für kürzere URL:http://goo.gl/zeJZl

Der Code:

def bytes2human(n, format="%(value)i%(symbol)s"):
    """
    >>> bytes2human(10000)
    '9K'
    >>> bytes2human(100001221)
    '95M'
    """
    symbols = ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
    prefix = {}
    for i, s in enumerate(symbols[1:]):
        prefix[s] = 1 << (i+1)*10
    for symbol in reversed(symbols[1:]):
        if n >= prefix[symbol]:
            value = float(n) / prefix[symbol]
            return format % locals()
    return format % dict(symbol=symbols[0], value=n)

Und auch eine Funktion für die Konvertierung in die andere Richtung (gleiche Seite):

def human2bytes(s):
    """
    >>> human2bytes('1M')
    1048576
    >>> human2bytes('1G')
    1073741824
    """
    symbols = ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
    letter = s[-1:].strip().upper()
    num = s[:-1]
    assert num.isdigit() and letter in symbols
    num = float(num)
    prefix = {symbols[0]:1}
    for i, s in enumerate(symbols[1:]):
        prefix[s] = 1 << (i+1)*10
    return int(num * prefix[letter])

Das ist großartig und alles, hat aber einige Informationsverluste, zum Beispiel:

>>> bytes2human(10000)
'9K'
>>> human2bytes('9K')
9216

Um dies zu lösen, ändere ich die Formatierung der Funktionbytes2human

In:format="%(value).3f%(symbol)s")

Welches ist viel schöner, mir diese Ergebnisse zu geben:

>>> bytes2human(10000)
'9.766K'

aber wenn ich versuche sie wieder mit dem umzuwandelnhuman2bytes Funktion:

>>> human2bytes('9.766K')

Traceback (most recent call last):
  File "<pyshell#366>", line 1, in <module>
    human2bytes('9.766K')
  File "<pyshell#359>", line 12, in human2bytes
    assert num.isdigit() and letter in symbols
AssertionError

Das liegt an der.

Meine Frage ist also, wie ich eine für Menschen lesbare Version ohne Datenverlust wieder in eine Byte-Version konvertieren kann.

Hinweis: Ich weiß, dass 3 Dezimalstellen auch ein bisschen Datenverlust sind. Aber für die Zwecke dieser Frage, lassen Sie uns das jetzt ignorieren, ich kann das immer in etwas Größeres ändern.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage