байты для человека читаемы и обратно. без потери данных
Мне нужно преобразовать строки, которые содержат использование памяти в байтах, например:1048576
(что составляет 1 млн.), именно так, в удобочитаемой версии, и наоборот.
ЗаписьЯ посмотрел здесь уже:Многоразовая библиотека, чтобы получить удобочитаемую версию размера файла?
И здесь (хотя это не Python):Как преобразовать читаемый человеком объем памяти в байты?
Ничто до сих пор не помогло мне, поэтому я посмотрел в другом месте.
Я нашел кое-что, что делает это для меня здесь:http://code.google.com/p/pyftpdlib/source/browse/trunk/test/bench.py?spec=svn984&r=984#137 или для более короткого URL:http://goo.gl/zeJZl
Код:
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)
А также функция для конвертации в другую сторону (тот же сайт):
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])
Это здорово и все, но в нем есть потеря информации, например:
>>> bytes2human(10000)
'9K'
>>> human2bytes('9K')
9216
Чтобы попытаться решить эту проблему, я изменяю форматирование в функцииbytes2human
В:format="%(value).3f%(symbol)s")
Что гораздо приятнее, давая мне такие результаты:
>>> bytes2human(10000)
'9.766K'
но когда я пытаюсь преобразовать их обратно сhuman2bytes
функция:
>>> 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
Это из-за.
Итак, мой вопрос: как я могу преобразовать читаемую человеком версию в байтовую версию без потери данных?
ЗаписьЯ знаю, что 3 знака после запятой - это тоже небольшая потеря данных. Но для целей этого вопроса давайте сейчас проигнорируем это, я всегда могу изменить это на что-то большее.