[python] 사람이 읽을 수있는 파일 크기 버전을 얻기 위해 재사용 가능한 라이브러리?

웹에는 바이트 크기에서 사람이 읽을 수있는 크기를 반환하는 기능을 제공하는 다양한 스 니펫이 있습니다.

>>> human_readable(2048)
'2 kilobytes'
>>>

그러나 이것을 제공하는 Python 라이브러리가 있습니까?



답변

간단한 구현으로 위의 “라이브러리를 요구하기에는 너무 작은 작업”문제를 해결합니다.

def sizeof_fmt(num, suffix='B'):
    for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
        if abs(num) < 1024.0:
            return "%3.1f%s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.1f%s%s" % (num, 'Yi', suffix)

지원합니다 :

  • 현재 알려진 모든 이진 접두사
  • 음수 및 양수
  • 1000 요비 바이트보다 큰 숫자
  • 임의의 단위 (아마도 Gibibits에서 계산하고 싶을 수도 있습니다!)

예:

>>> sizeof_fmt(168963795964)
'157.4GiB'

에 의해 Fred Cirera


답변

찾고있는 모든 기능을 갖춘 라이브러리는 humanize입니다. humanize.naturalsize()당신이 찾고있는 모든 것을하는 것 같습니다.


답변

여기 내 버전이 있습니다. for-loop를 사용하지 않습니다. 상수 복잡도는 O ( 1 )이며 for-loop를 사용하는 답변보다 이론적으로 더 효율적입니다.

from math import log
unit_list = zip(['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2])
def sizeof_fmt(num):
    """Human friendly file size"""
    if num > 1:
        exponent = min(int(log(num, 1024)), len(unit_list) - 1)
        quotient = float(num) / 1024**exponent
        unit, num_decimals = unit_list[exponent]
        format_string = '{:.%sf} {}' % (num_decimals)
        return format_string.format(quotient, unit)
    if num == 0:
        return '0 bytes'
    if num == 1:
        return '1 byte'

진행 상황을보다 명확하게하기 위해 문자열 형식에 대한 코드를 생략 할 수 있습니다. 실제로 작업을 수행하는 행은 다음과 같습니다.

exponent = int(log(num, 1024))
quotient = num / 1024**exponent
unit_list[exponent]


답변

파이썬 3.6 이상에서 다음과 같은 작품은 내 의견으로는 여기에서 가장 이해하기 쉬운 대답이며 사용되는 소수 자릿수를 사용자 정의 할 수 있습니다.

def human_readable_size(size, decimal_places=3):
    for unit in ['B','KiB','MiB','GiB','TiB']:
        if size < 1024.0:
            break
        size /= 1024.0
    return f"{size:.{decimal_places}f}{unit}"


답변

나는이 질문이 고대라는 것을 알고 있지만 최근에는 루프를 피하는 버전을 생각해 냈습니다 log2.

from math import log2

_suffixes = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']

def file_size(size):
    # determine binary order in steps of size 10 
    # (coerce to int, // still returns a float)
    order = int(log2(size) / 10) if size else 0
    # format file size
    # (.4g results in rounded numbers for exact matches and max 3 decimals, 
    # should never resort to exponent values)
    return '{:.4g} {}'.format(size / (1 << (order * 10)), _suffixes[order])

가독성으로 인해 비유의로 간주 될 수 있습니다. 🙂


답변

항상 그 녀석 중 하나가 있어야합니다. 오늘은 나야 함수 서명을 세면 한 줄짜리 솔루션 또는 두 줄입니다.

def human_size(bytes, units=[' bytes','KB','MB','GB','TB', 'PB', 'EB']):
    """ Returns a human readable string reprentation of bytes"""
    return str(bytes) + units[0] if bytes < 1024 else human_size(bytes>>10, units[1:])

>>> human_size(123)
123 bytes
>>> human_size(123456789)
117GB


답변

Django가 설치된 경우 filesizeformat 을 사용해 볼 수도 있습니다 .

from django.template.defaultfilters import filesizeformat
filesizeformat(1073741824)

=>

"1.0 GB"