在資料庫中存儲時,使用 Bytes 更精確,可擴展性和靈活性都很高。輸出時,需要做一些適配。1. 註意事項與測試代碼需要考慮sizeInBytes為 None 的場景。除以 1024.0 而非 1024,避免丟失精度。實現的函數為getSizeInMb(sizeInBytes),通用的測試代碼為de...
在資料庫中存儲時,使用 Bytes 更精確,可擴展性和靈活性都很高。
輸出時,需要做一些適配。
1. 註意事項與測試代碼
- 需要考慮 sizeInBytes 為 None 的場景。
- 除以 1024.0 而非 1024,避免丟失精度。
實現的函數為 getSizeInMb(sizeInBytes),通用的測試代碼為
def getSizeInMb(sizeInBytes): return 0 def test(sizeInBytes): print '%s -> %s' % (sizeInBytes, getSizeInMb(sizeInBytes)) test(None) test(0) test(10240000) test(1024*1024*10)
2. 以 MB 為單位輸出 -- 返回 float
通常,電子書的大小在 1 - 50MB 之間,輸出時統一轉為 MB 是不錯的選擇。
弊端:
- 輸出精度過高,比如 10240000 Bytes 計算結果為 10240000 -> 9.765625
- 文件大小有限制,小於 1 MB 或 G 級數據不適合該方式展示
優勢:
- 適合於用返回值參與計算
def getSizeInMb(sizeInBytes): return (sizeInBytes or 0) / (1024.0*1024.0)
3. 以 MB 為單位保留 1 位小數 -- 返回 str
處於精度問題考慮,可以選擇保留 1 位小數。
def getSizeInMb(sizeInBytes): return '%.1f' % ((sizeInBytes or 0) / (1024.0*1024.0), ) # use 1-dimension tuple is suggested
返回值建議寫成 '%.1f' % (number,) 而非 '%.1f' % (number)
二者均能正確執行,但後者容易被誤判為執行只有一個參數 number 的函數,導致難以判斷的錯誤。
3. 以 MB 為單位保留至多 1 位小數 -- 返回 str
大多數操作系統一般展示至多 1 位小數
def getSizeInMb(sizeInBytes): sizeInMb = '%.1f' % ((sizeInBytes or 0) / (1024.0*1024.0), ) # use 1-dimension tuple is suggested return sizeInMb[:-2] if sizeInMb.endswith('.0') else sizeInMb # python2.5+ required
4. 自動選擇最佳單位
def getSizeInNiceString(sizeInBytes): """ Convert the given byteCount into a string like: 9.9bytes/KB/MB/GB """ for (cutoff, label) in [(1024*1024*1024, "GB"), (1024*1024, "MB"), (1024, "KB"), ]: if sizeInBytes >= cutoff: return "%.1f %s" % (sizeInBytes * 1.0 / cutoff, label) if sizeInBytes == 1: return "1 byte" else: bytes = "%.1f" % (sizeInBytes or 0,) return (bytes[:-2] if bytes.endswith('.0') else bytes) + ' bytes'
演算法說明:
1. 從英語語法角度,只有 1 使用單數形式。其他 0/小數 均使用複數形式。涉及 bytes 級別
2. 精度方面,KB 及以上級別,保留 1 位小數。bytes 保留至多 1 位小數。
這種處理規則,不適合於小數十分位為 0 的情況,比如 10.0 bytes,10.01 bytes。輸入結果均為 10 bytes。
其他情況下,精度均不存在問題。
測試數據與結果如下圖