我需要使用Python转换一个人类可读的上传大小限制符号(例如100kb、32MB等)。转换后的值应表示为字节数。
例子
convert_size_to_bytes("32MB") # should return 33554432
convert_size_to_bytes("100kB") # should return 102400
convert_size_to_bytes("123B") # should return 123
convert_size_to_bytes("123") # should return 123
最佳答案
我喜欢@Robson所采取的简单方法,但我注意到它有很多角落的案例没有处理。以下版本基本相同,但它添加/修复了以下内容:
。
支持单数单位,例如“1字节”
增加了对yottabytes、zetabytes等的支持。上面的版本将崩溃。
在输入前、后和中添加对空格的支持。
添加对浮动(“5.2 mb”)的支持
较大的docstring
代码如下:
def convert_size_to_bytes(size_str):
"""Convert human filesizes to bytes.
Special cases:
- singular units, e.g., "1 byte"
- byte vs b
- yottabytes, zetabytes, etc.
- with & without spaces between & around units.
- floats ("5.2 mb")
To reverse this, see hurry.filesize or the Django filesizeformat template
filter.
:param size_str: A human-readable string representing a file size, e.g.,
"22 megabytes".
:return: The number of bytes represented by the string.
"""
multipliers = {
'kilobyte': 1024,
'megabyte': 1024 ** 2,
'gigabyte': 1024 ** 3,
'terabyte': 1024 ** 4,
'petabyte': 1024 ** 5,
'exabyte': 1024 ** 6,
'zetabyte': 1024 ** 7,
'yottabyte': 1024 ** 8,
'kb': 1024,
'mb': 1024**2,
'gb': 1024**3,
'tb': 1024**4,
'pb': 1024**5,
'eb': 1024**6,
'zb': 1024**7,
'yb': 1024**8,
}
for suffix in multipliers:
size_str = size_str.lower().strip().strip('s')
if size_str.lower().endswith(suffix):
return int(float(size_str[0:-len(suffix)]) * multipliers[suffix])
else:
if size_str.endswith('b'):
size_str = size_str[0:-1]
elif size_str.endswith('byte'):
size_str = size_str[0:-4]
return int(size_str)
我写了一系列的测试来测试我们正在抹去的价值观:
class TestFilesizeConversions(TestCase):
def test_filesize_conversions(self):
"""Can we convert human filesizes to bytes?"""
qa_pairs = [
('58 kb', 59392),
('117 kb', 119808),
('117kb', 119808),
('1 byte', 1),
('117 bytes', 117),
('117 bytes', 117),
(' 117 bytes ', 117),
('117b', 117),
('117bytes', 117),
('1 kilobyte', 1024),
('117 kilobytes', 119808),
('0.7 mb', 734003),
('1mb', 1048576),
('5.2 mb', 5452595),
]
for qa in qa_pairs:
print("Converting '%s' to bytes..." % qa[0], end='')
self.assertEqual(convert_size_to_bytes(qa[0]), qa[1])
print('✓')