Existem vários trechos na Web que oferecem uma função para retornar o tamanho legível humano do tamanho de bytes:
>>> human_readable(2048)
'2 kilobytes'
>>>
Mas existe uma biblioteca Python que fornece isso?
python
code-snippets
filesize
Sridhar Ratnakumar
fonte
fonte
Respostas:
Resolvendo o problema "tarefa muito pequena para exigir uma biblioteca" acima, por uma implementação direta:
Apoia:
Exemplo:
por Fred Cirera
fonte
B
seja (ou seja, para unidades que não sejam bytes) você deseja que o fator seja1000.0
e não1024.0
não?1
linhas 4 e 6 para a precisão desejada.É uma biblioteca que possui todas as funcionalidades que você procura
humanize
.humanize.naturalsize()
parece fazer tudo o que você está procurando.fonte
humanize.naturalsize(2048) # => '2.0 kB'
,humanize.naturalsize(2048, binary=True) # => '2.0 KiB'
humanize.naturalsize(2048, gnu=True) # => '2.0K'
Aqui está a minha versão. Ele não usa um loop for. Tem complexidade constante, O ( 1 ), e é, em teoria, mais eficiente do que as respostas aqui que usam um loop for.
Para deixar mais claro o que está acontecendo, podemos omitir o código para a formatação da string. Aqui estão as linhas que realmente fazem o trabalho:
fonte
1000
mostrar como1,000 bytes
.unit_list = list(zip(['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2]))
O seguinte trabalho em Python 3.6+, é, na minha opinião, a resposta mais fácil de entender aqui e permite personalizar a quantidade de casas decimais usadas.
fonte
Embora eu saiba que essa pergunta é antiga, recentemente criei uma versão que evita loops, usando
log2
para determinar a ordem do tamanho que funciona como uma mudança e um índice na lista de sufixos:No entanto, poderia ser considerado não sintético por sua legibilidade :)
fonte
size
ou(1 << (order * 10)
emfloat()
na última linha (para python 2).import math
lá em cima.Sempre tem que haver um desses caras. Bem, hoje sou eu. Aqui está uma solução de uma linha - ou duas linhas, se você contar a assinatura da função.
fonte
units=None
vez disso))Se você estiver usando o Django instalado, também poderá tentar o filesizeformat :
fonte
Uma dessas bibliotecas é hurry.filesize .
fonte
Usar potências de 1000 ou kibibytes seria mais amigável ao padrão:
PS Nunca confie em uma biblioteca que imprima milhares com o sufixo K (maiúsculo) :)
fonte
P.S. Never trust a library that prints thousands with the K (uppercase) suffix :)
Por que não? O código pode ser perfeitamente correto e o autor simplesmente não considerou a embalagem do quilo. Parece bastante estúpido para descartar automaticamente qualquer código baseado em sua regra ...Isso fará o que você precisa em quase qualquer situação, é personalizável com argumentos opcionais e, como você pode ver, é praticamente auto-documentado:
Exemplo de saída:
Personalizações avançadas:
Este código é compatível com Python 2 e Python 3. A conformidade com o PEP8 é um exercício para o leitor. Lembre-se, é a saída que é bonita.
Atualizar:
Se você precisar de milhares de vírgulas, basta aplicar a extensão óbvia:
Por exemplo:
fonte
Você deve usar "humanizar".
fonte
Analisando o snippet fornecido como uma alternativa ao hurry.filesize (), aqui está um snippet que fornece vários números de precisão com base no prefixo usado. Não é tão conciso quanto alguns trechos, mas eu gosto dos resultados.
fonte
O projeto HumanFriendly ajuda nisso .
O código acima fornecerá 1 KB como resposta.
Exemplos podem ser encontrados aqui .
fonte
Com base em todas as respostas anteriores, aqui está minha opinião. É um objeto que armazena o tamanho do arquivo em bytes como um número inteiro. Mas quando você tenta imprimir o objeto, você obtém automaticamente uma versão legível por humanos.
fonte
Eu gosto da precisão fixa da versão decimal do remetente , então aqui está uma espécie de híbrido disso com a resposta do joctee acima (você sabia que poderia receber logs com bases não inteiras?):
fonte
DiveIntoPython3 também fala sobre essa função.
fonte
O Django moderno tem uma tag de modelo próprio
filesizeformat
:Formata o valor como um
human-readable
tamanho de arquivo (por exemplo, '13 KB ',' 4.1 MB ',' 102 bytes 'etc.).Por exemplo:
Se o valor for 123456789, a saída seria 117,7 MB.
Mais informações: https://docs.djangoproject.com/en/1.10/ref/templates/builtins/#filesizeformat
fonte
Que tal um liner 2 simples:
Aqui está como ele funciona sob o capô:
Kb
, então a resposta deve ser X KiB)file_size/value_of_closest_unit
junto com a unidade.No entanto, não funciona se o tamanho do arquivo for 0 ou negativo (porque o log não está definido para os números 0 e -ve). Você pode adicionar verificações extras para eles:
Exemplos:
NOTA - Há uma diferença entre Kb e KiB. KB significa 1000 bytes, enquanto KiB significa 1024 bytes. KB, MB, GB são múltiplos de 1000, enquanto KiB, MiB, GiB etc são múltiplos de 1024. Saiba mais aqui
fonte
fonte
O que você está prestes a encontrar abaixo não é, de maneira alguma, a solução mais eficiente ou mais curta dentre as já postadas. Em vez disso, concentra-se em uma questão em particular que muitas das outras respostas perdem.
Nomeadamente, o caso em que
999_995
é dada entrada como :sendo truncado para o número inteiro mais próximo e aplicado de volta à entrada,
Isso parece ser exatamente o que esperávamos até sermos obrigados a controlar a precisão da saída . E é aí que as coisas começam a ficar um pouco difíceis.
Com a precisão definida para 2 dígitos, obtemos:
em vez de
1M
.Como podemos combater isso?
Obviamente, podemos verificar isso explicitamente:
Mas podemos fazer melhor? Podemos saber para que lado
order
devemos cortar antes de dar o passo final?Acontece que podemos.
Supondo uma regra de arredondamento decimal de 0,5, a
if
condição acima se traduz em:resultando em
dando
fonte
referem-se
Sridhar Ratnakumar
's resposta, actualizada para:e o exemplo de saída é:
fonte
Essa solução também pode agradar a você, dependendo de como sua mente funciona:
fonte