bytes para legível por humanos e vice-versa. sem perda de dados
Eu preciso converter seqüências de caracteres que contêm o uso de memória em bytes, como:1048576
(que é 1M) exatamente isso, uma versão legível e vice-versa.
Nota: Eu olhei aqui já:Biblioteca reutilizável para obter uma versão legível por humanos do tamanho do arquivo?
E aqui (mesmo que não seja python):Como converter o tamanho da memória legível em bytes?
Nada até agora me ajudou, então eu procurei em outro lugar.
Eu encontrei algo que faz isso por mim aqui:http://code.google.com/p/pyftpdlib/source/browse/trunk/test/bench.py?spec=svn984&r=984#137 ou, para um URL mais curto:http://goo.gl/zeJZl
O código:
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)
E também uma função para conversão de outra maneira (mesmo site):
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])
Isso é ótimo e tudo, mas tem alguma perda de informação, exemplo:
>>> bytes2human(10000)
'9K'
>>> human2bytes('9K')
9216
Para tentar resolver isso, mudo a formatação da funçãobytes2human
Para dentro:format="%(value).3f%(symbol)s")
O que é muito melhor, me dando estes resultados:
>>> bytes2human(10000)
'9.766K'
mas quando eu tento convertê-los de volta com ohuman2bytes
função:
>>> 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
Isso é por causa do.
Então, minha pergunta é: como posso converter uma versão legível de volta para a versão de byte, sem perda de dados?
Nota: Eu sei que 3 casas decimais também são um pouco de perda de dados. Mas para os propósitos desta questão, vamos ignorar isso por enquanto, eu sempre posso mudar isso para algo maior.