Voici comment je procède :
from bisect import bisect
def to_filesize(bytes_num, si=True):
decade = 1000 if si else 1024
partitions = tuple(decade ** n for n in range(1, 6))
suffixes = tuple('BKMGTP')
i = bisect(partitions, bytes_num)
s = suffixes[i]
for n in range(i):
bytes_num /= decade
f = '{:.3f}'.format(bytes_num)
return '{}{}'.format(f.rstrip('0').rstrip('.'), s)
Il imprime jusqu'à trois décimales et supprime les zéros et les points qui suivent. Le paramètre booléen si
permet d'alterner l'utilisation d'une magnitude de taille basée sur 10 et d'une magnitude de taille basée sur 2.
Voici son pendant. Il permet d'écrire des fichiers de configuration propres comme {'maximum_filesize': from_filesize('10M')
. Il renvoie un nombre entier qui correspond approximativement à la taille de fichier prévue. Je n'utilise pas de décalage de bits parce que la valeur source est un nombre à virgule flottante (il acceptera from_filesize('2.15M')
très bien). La conversion en nombre entier/décimal fonctionnerait, mais rendrait le code plus compliqué, alors qu'il fonctionne déjà tel quel.
def from_filesize(spec, si=True):
decade = 1000 if si else 1024
suffixes = tuple('BKMGTP')
num = float(spec[:-1])
s = spec[-1]
i = suffixes.index(s)
for n in range(i):
num *= decade
return int(num)