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


238

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

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

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


2
나는 이것이 "도서관을 요구하기에는 너무 작은 과제"라는 제목에 속한다고 생각한다. hurry.filesize의 소스를 살펴보면 수십 줄의 코드가있는 단 하나의 함수 만 있습니다. 심지어 압축 될 수도 있습니다.
벤 블랭크

8
라이브러리를 사용하면 얻을 수있는 장점은 일반적으로 테스트한다는 것입니다 (편집에 버그가있는 경우 실행할 수있는 테스트 포함). 테스트를 추가하면 더 이상 '수십 줄의 코드'가 아닙니다. :-)
Sridhar Ratnakumar

파이썬 커뮤니티에서 바퀴를 다시 발명하는 양은 미친 듯이 말도 안됩니다. ls -h /path/to/file.ext만이 작업을 수행합니다. 그러나 대답은 좋은 일을하고 있습니다. 쿠도
Edward Aung

답변:


522

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

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


4
숫자와 단위 사이에 공백이 있어야합니다. HTML 또는 라텍스를 출력하는 경우 공백이 아닌 공간이어야합니다.
josch

3
그냥 생각하지만 B바이트가 아닌 다른 단위의 접미사에 대해 인수 1000.01024.0아니오 가 아니라고 싶습니까?
Anentropic

5
10 진수 구성 요소의 정밀도를 높이려면 14 행과 6 행을 원하는 정밀도로 변경하십시오 .
Matthew G

44
이 "너무 작은 작업"에 대한이 모든 반복이 캡처되어 테스트를 통해 라이브러리에 캡슐화되면 좋을 것입니다.
fess.

6
@ MD004 다른 방법입니다. 접두사는 1 KB = 1000 B 및 1 KiB = 1024 B가되도록 정의됩니다.
augurar

116

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


9
영업의 데이터를 사용하여 몇 가지 예 : humanize.naturalsize(2048) # => '2.0 kB' ,humanize.naturalsize(2048, binary=True) # => '2.0 KiB' humanize.naturalsize(2048, gnu=True) # => '2.0K'
RubenLaguna

32

여기 내 버전이 있습니다. 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]

2
짧은 코드를 최적화하는 것에 대해 이야기하는 동안 if / elif / else를 사용하지 않는 이유는 무엇입니까? 음수 파일 크기를 예상하지 않는 한 마지막 확인 num == 1은 필요하지 않습니다. 그렇지 않으면 : 좋은 작품, 나는이 버전을 좋아한다.
ted

2
내 코드는 확실히 더 최적화 될 수 있습니다. 그러나 필자의 요점은이 작업이 일정한 복잡성으로 해결 될 수 있음을 보여주는 것이었다.
joctee

37
for 루프에 대한 답은 O (1)입니다. for 루프가 제한되어 있기 때문에 계산 시간이 입력 크기에 비례하지 않습니다 (무한한 SI 접두사가 없음).
Thomas Minor

1
형식화를 위해 쉼표를 추가해야하므로로 1000표시됩니다 1,000 bytes.
iTayb

3
Python 3을 사용할 때 zip은 반복자를 반환하므로 list ()로 감싸 야합니다. unit_list = list(zip(['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2]))
donarb 2019

30

파이썬 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}"

26

나는이 질문이 고대라는 것을 알고 있지만 최근에는 루프를 피하는 버전을 생각해 냈습니다 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])

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


1
log2 일을 좋아하지만 size == 0을 처리해야합니다!
Marti Nito

당신도 포장 할 필요가 size(1 << (order * 10)float()(파이썬 2) 마지막 줄에.
Harvey

참고 : 일부는 필요할 import math수 있습니다.
monsto 2019

@monsto true, added :)
akaIDIOT

이것이 얼마나 컴팩트한지 사랑하십시오! 공유해 주셔서 감사합니다.
John Crawford

17

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

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

1
참고로 출력은 항상 내림됩니다.
wp-overwatch.com

1
목록을 기본 인수로 사용하지 않도록 메소드 내부의 단위에 기본 목록을 지정하는 것이 좋지 않습니까? (및 units=None대신 사용)
Imanol

3
@ImanolEizaguirre 모범 사례에 따르면 제안한대로 수행하는 것이 좋습니다. 실수로 프로그램에 버그를 도입하지 않습니다. 그러나이 기능은 작성된대로 사용되므로 장치 목록이 조작되지 않으므로 안전합니다. 조작 된 경우 변경 사항은 영구적이며 후속 함수 호출은 조작 된 버전의 목록을 units 인수의 기본 인수로 수신합니다.
wp-overwatch.com

파이썬 3의 경우 소수점을 원한다면 대신 이것을 사용하십시오 :```def human_size (fsize, units = [ 'bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']) : "{: .2f} {}". format (float (fsize), units [0]) 반환 fsize <1024 인 경우 human_size (fsize / 1024, units [1 :])```
Omer

15

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

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

=>

"1.0 GB"

1
나에게 이것의 한 가지 단점은 1024로 나누더라도 GiB 대신 GB를 사용한다는 것이다.
Pepedou

9

그러한 라이브러리 중 하나는 hurry.filesize 입니다.

>>> from hurry.filesize import alternative
>>> size(1, system=alternative)
'1 byte'
>>> size(10, system=alternative)
'10 bytes'
>>> size(1024, system=alternative)
'1 KB'

3
그러나이 라이브러리는 사용자 정의 할 수 없습니다. >>> hurry.filesize 가져 오기 크기에서 >>> size (1031053) >>> size (3033053) '2M'예를 들어 '2.4M'또는 '2423K'.. 2M '.
Sridhar Ratnakumar

또한 의존성 시스템 등을 다루는 경우 hurry.filesize에서 코드를 가져 와서 자신의 코드에 직접 넣는 것이 매우 쉽습니다. 사람들이 제공하는 스 니펫만큼 짧습니다.
mlissner

@SridharRatnakumar는 과도 근사 문제를 다소 지능적으로 해결하기 위해 수학적 해킹을 참조하십시오 . 접근 방식을 더욱 개선 할 수 있습니까?
Acumenus

9

1000 또는 kibibyte의 힘을 사용하는 것이 더 표준 친화적입니다.

def sizeof_fmt(num, use_kibibyte=True):
    base, suffix = [(1000.,'B'),(1024.,'iB')][use_kibibyte]
    for x in ['B'] + map(lambda x: x+suffix, list('kMGTP')):
        if -base < num < base:
            return "%3.1f %s" % (num, x)
        num /= base
    return "%3.1f %s" % (num, x)

PS는 K (대문자) 접미사로 수천을 인쇄하는 라이브러리를 신뢰하지 않습니다. :)


P.S. Never trust a library that prints thousands with the K (uppercase) suffix :)왜 안돼? 코드는 완벽하게 들릴 수 있으며 저자는 킬로 케이싱을 고려하지 않았습니다. 규칙에 따라 모든 코드를 자동으로 닫는 것은 꽤 어리석은 것 같습니다 ...
Douglas Gaskell

7

이것은 거의 모든 상황에서 무엇을해야 할 것이다, 선택적 인수와 사용자 정의 할 수 있습니다, 당신은 볼 수있다 많은자가 설명 :

from math import log
def pretty_size(n,pow=0,b=1024,u='B',pre=['']+[p+'i'for p in'KMGTPEZY']):
    pow,n=min(int(log(max(n*b**pow,1),b)),len(pre)-1),n*b**pow
    return "%%.%if %%s%%s"%abs(pow%(-pow-1))%(n/b**float(pow),pre[pow],u)

출력 예 :

>>> pretty_size(42)
'42 B'

>>> pretty_size(2015)
'2.0 KiB'

>>> pretty_size(987654321)
'941.9 MiB'

>>> pretty_size(9876543210)
'9.2 GiB'

>>> pretty_size(0.5,pow=1)
'512 B'

>>> pretty_size(0)
'0 B'

고급 사용자 정의 :

>>> pretty_size(987654321,b=1000,u='bytes',pre=['','kilo','mega','giga'])
'987.7 megabytes'

>>> pretty_size(9876543210,b=1000,u='bytes',pre=['','kilo','mega','giga'])
'9.9 gigabytes'

이 코드는 Python 2 및 Python 3과 호환됩니다. PEP8 준수는 독자를위한 연습입니다. 그것은의 기억 출력 꽤입니다.

최신 정보:

수천 개의 쉼표가 필요한 경우 다음 확장명을 적용하십시오.

def prettier_size(n,pow=0,b=1024,u='B',pre=['']+[p+'i'for p in'KMGTPEZY']):
    r,f=min(int(log(max(n*b**pow,1),b)),len(pre)-1),'{:,.%if} %s%s'
    return (f%(abs(r%(-r-1)),pre[r],u)).format(n*b**pow/b**float(r))

예를 들면 다음과 같습니다.

>>> pretty_units(987654321098765432109876543210)
'816,968.5 YiB'


6

hurry.filesize ()의 대안으로 제공된 스 니펫을 리핑하면 사용 된 접두사에 따라 다양한 정밀도 숫자를 제공하는 스 니펫이 있습니다. 일부 스 니펫만큼 간결하지는 않지만 결과가 마음에 듭니다.

def human_size(size_bytes):
    """
    format a size in bytes into a 'human' file size, e.g. bytes, KB, MB, GB, TB, PB
    Note that bytes/KB will be reported in whole numbers but MB and above will have greater precision
    e.g. 1 byte, 43 bytes, 443 KB, 4.3 MB, 4.43 GB, etc
    """
    if size_bytes == 1:
        # because I really hate unnecessary plurals
        return "1 byte"

    suffixes_table = [('bytes',0),('KB',0),('MB',1),('GB',2),('TB',2), ('PB',2)]

    num = float(size_bytes)
    for suffix, precision in suffixes_table:
        if num < 1024.0:
            break
        num /= 1024.0

    if precision == 0:
        formatted_size = "%d" % num
    else:
        formatted_size = str(round(num, ndigits=precision))

    return "%s %s" % (formatted_size, suffix)


4

이전의 모든 답변을 바탕으로 여기에 내가 취합니다. 바이트 단위로 파일 크기를 정수로 저장하는 객체입니다. 그러나 객체를 인쇄하려고하면 사람이 읽을 수있는 버전이 자동으로 제공됩니다.

class Filesize(object):
    """
    Container for a size in bytes with a human readable representation
    Use it like this::

        >>> size = Filesize(123123123)
        >>> print size
        '117.4 MB'
    """

    chunk = 1024
    units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB']
    precisions = [0, 0, 1, 2, 2, 2]

    def __init__(self, size):
        self.size = size

    def __int__(self):
        return self.size

    def __str__(self):
        if self.size == 0: return '0 bytes'
        from math import log
        unit = self.units[min(int(log(self.size, self.chunk)), len(self.units) - 1)]
        return self.format(unit)

    def format(self, unit):
        if unit not in self.units: raise Exception("Not a valid file size unit: %s" % unit)
        if self.size == 1 and unit == 'bytes': return '1 byte'
        exponent = self.units.index(unit)
        quotient = float(self.size) / self.chunk**exponent
        precision = self.precisions[exponent]
        format_string = '{:.%sf} {}' % (precision)
        return format_string.format(quotient, unit)

3

나는 senderle의 decimal 버전의 고정 정밀도를 좋아하기 때문에 위의 joctee의 답변과 일종의 하이브리드가 있습니다 (정수가 아닌베이스로 로그를 취할 수 있다는 것을 알고 있습니까?) :

from math import log
def human_readable_bytes(x):
    # hybrid of https://stackoverflow.com/a/10171475/2595465
    #      with https://stackoverflow.com/a/5414105/2595465
    if x == 0: return '0'
    magnitude = int(log(abs(x),10.24))
    if magnitude > 16:
        format_str = '%iP'
        denominator_mag = 15
    else:
        float_fmt = '%2.1f' if magnitude % 3 == 1 else '%1.2f'
        illion = (magnitude + 1) // 3
        format_str = float_fmt + ['', 'K', 'M', 'G', 'T', 'P'][illion]
    return (format_str % (x * 1.0 / (1024 ** illion))).lstrip('0')



2

간단한 2 라이너는 어떻습니까?

def humanizeFileSize(filesize):
    p = int(math.floor(math.log(filesize, 2)/10))
    return "%.3f%s" % (filesize/math.pow(1024,p), ['B','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'][p])

후드 아래에서 작동하는 방법은 다음과 같습니다.

  1. 로그 2를 계산합니다 (파일 크기).
  2. 가장 가까운 단위를 얻기 위해 10으로 나눕니다. (예 : size가 5000 바이트 인 경우 가장 가까운 단위는 Kb이므로 답은 X KiB 여야합니다)
  3. file_size/value_of_closest_unit단위와 함께 반환합니다 .

그러나 filesize가 0이거나 음수이면 (0과 -ve 숫자에 대해 로그가 정의되어 있지 않기 때문에) 작동하지 않습니다. 추가 검사를 추가 할 수 있습니다.

def humanizeFileSize(filesize):
    filesize = abs(filesize)
    if (filesize==0):
        return "0 Bytes"
    p = int(math.floor(math.log(filesize, 2)/10))
    return "%0.2f %s" % (filesize/math.pow(1024,p), ['Bytes','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'][p])

예 :

>>> humanizeFileSize(538244835492574234)
'478.06 PiB'
>>> humanizeFileSize(-924372537)
'881.55 MiB'
>>> humanizeFileSize(0)
'0 Bytes'

참고 -Kb와 KiB에는 차이가 있습니다. KB는 1000 바이트를 의미하고 KiB는 1024 바이트를 의미합니다. KB, MB, GB는 등 킬로바이트 해당 MIB, 지브 반면 1024의 모든 배수는 1000의 모든 배수 여기에 대해 더 많은


1
def human_readable_data_quantity(quantity, multiple=1024):
    if quantity == 0:
        quantity = +0
    SUFFIXES = ["B"] + [i + {1000: "B", 1024: "iB"}[multiple] for i in "KMGTPEZY"]
    for suffix in SUFFIXES:
        if quantity < multiple or suffix == SUFFIXES[-1]:
            if suffix == SUFFIXES[0]:
                return "%d%s" % (quantity, suffix)
            else:
                return "%.1f%s" % (quantity, suffix)
        else:
            quantity /= multiple

1

아래에서 찾으려는 것은 이미 게시 된 솔루션 중 가장 성능이 우수하거나 최단 솔루션이 아닙니다. 대신 하나의 특정 문제 에 중점을 둡니다. 많은 다른 답변에서 놓친 .

즉, like like 입력 999_995이 주어진 경우 :

Python 3.6.1 ...
...
>>> value = 999_995
>>> base = 1000
>>> math.log(value, base)
1.999999276174054

가장 가까운 정수로 자르고 입력에 다시 적용하면

>>> order = int(math.log(value, base))
>>> value/base**order
999.995

이것은 출력 정밀도 를 제어해야 할 때까지 정확히 예상되는 것 같습니다 . 그리고 이것은 상황이 조금 어려워지기 시작할 때입니다.

정밀도가 2 자리로 설정되면 다음을 얻습니다.

>>> round(value/base**order, 2)
1000 # K

대신에 1M.

어떻게 대응할 수 있습니까?

물론 명시 적으로 확인할 수 있습니다.

if round(value/base**order, 2) == base:
    order += 1

그러나 우리는 더 잘할 수 있습니까? order마지막 단계를 수행하기 전에 어떤 방법 으로 절단해야하는지 알 수 있습니까 ?

우리가 할 수있는 것으로 밝혀졌습니다.

소수점 이하 반올림 규칙을 가정하면 위의 if조건 은 다음과 같이 해석됩니다.

여기에 이미지 설명을 입력하십시오

~를 야기하는

def abbreviate(value, base=1000, precision=2, suffixes=None):
    if suffixes is None:
        suffixes = ['', 'K', 'M', 'B', 'T']

    if value == 0:
        return f'{0}{suffixes[0]}'

    order_max = len(suffixes) - 1
    order = log(abs(value), base)
    order_corr = order - int(order) >= log(base - 0.5/10**precision, base)
    order = min(int(order) + order_corr, order_max)

    factored = round(value/base**order, precision)

    return f'{factored:,g}{suffixes[order]}'

기부

>>> abbreviate(999_994)
'999.99K'
>>> abbreviate(999_995)
'1M'
>>> abbreviate(999_995, precision=3)
'999.995K'
>>> abbreviate(2042, base=1024)
'1.99K'
>>> abbreviate(2043, base=1024)
'2K'

0

Sridhar Ratnakumar의 답변을 참조하십시오 .

def formatSize(sizeInBytes, decimalNum=1, isUnitWithI=False, sizeUnitSeperator=""):
  """format size to human readable string"""
  # https://en.wikipedia.org/wiki/Binary_prefix#Specific_units_of_IEC_60027-2_A.2_and_ISO.2FIEC_80000
  # K=kilo, M=mega, G=giga, T=tera, P=peta, E=exa, Z=zetta, Y=yotta
  sizeUnitList = ['','K','M','G','T','P','E','Z']
  largestUnit = 'Y'

  if isUnitWithI:
    sizeUnitListWithI = []
    for curIdx, eachUnit in enumerate(sizeUnitList):
      unitWithI = eachUnit
      if curIdx >= 1:
        unitWithI += 'i'
      sizeUnitListWithI.append(unitWithI)

    # sizeUnitListWithI = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
    sizeUnitList = sizeUnitListWithI

    largestUnit += 'i'

  suffix = "B"
  decimalFormat = "." + str(decimalNum) + "f" # ".1f"
  finalFormat = "%" + decimalFormat + sizeUnitSeperator + "%s%s" # "%.1f%s%s"
  sizeNum = sizeInBytes
  for sizeUnit in sizeUnitList:
      if abs(sizeNum) < 1024.0:
        return finalFormat % (sizeNum, sizeUnit, suffix)
      sizeNum /= 1024.0
  return finalFormat % (sizeNum, largestUnit, suffix)

예제 출력은 다음과 같습니다.

def testKb():
  kbSize = 3746
  kbStr = formatSize(kbSize)
  print("%s -> %s" % (kbSize, kbStr))

def testI():
  iSize = 87533
  iStr = formatSize(iSize, isUnitWithI=True)
  print("%s -> %s" % (iSize, iStr))

def testSeparator():
  seperatorSize = 98654
  seperatorStr = formatSize(seperatorSize, sizeUnitSeperator=" ")
  print("%s -> %s" % (seperatorSize, seperatorStr))

def testBytes():
  bytesSize = 352
  bytesStr = formatSize(bytesSize)
  print("%s -> %s" % (bytesSize, bytesStr))

def testMb():
  mbSize = 76383285
  mbStr = formatSize(mbSize, decimalNum=2)
  print("%s -> %s" % (mbSize, mbStr))

def testTb():
  tbSize = 763832854988542
  tbStr = formatSize(tbSize, decimalNum=2)
  print("%s -> %s" % (tbSize, tbStr))

def testPb():
  pbSize = 763832854988542665
  pbStr = formatSize(pbSize, decimalNum=4)
  print("%s -> %s" % (pbSize, pbStr))


def demoFormatSize():
  testKb()
  testI()
  testSeparator()
  testBytes()
  testMb()
  testTb()
  testPb()

  # 3746 -> 3.7KB
  # 87533 -> 85.5KiB
  # 98654 -> 96.3 KB
  # 352 -> 352.0B
  # 76383285 -> 72.84MB
  # 763832854988542 -> 694.70TB
  # 763832854988542665 -> 678.4199PB

0

이 솔루션은 또한 당신의 마음이 어떻게 작동하는지에 따라 당신에게 호소 할 수 있습니다 :

from pathlib import Path    

def get_size(path = Path('.')):
    """ Gets file size, or total directory size """
    if path.is_file():
        size = path.stat().st_size
    elif path.is_dir():
        size = sum(file.stat().st_size for file in path.glob('*.*'))
    return size

def format_size(path, unit="MB"):
    """ Converts integers to common size units used in computing """
    bit_shift = {"B": 0,
            "kb": 7,
            "KB": 10,
            "mb": 17,
            "MB": 20,
            "gb": 27,
            "GB": 30,
            "TB": 40,}
    return "{:,.0f}".format(get_size(path) / float(1 << bit_shift[unit])) + " " + unit

# Tests and test results
>>> get_size("d:\\media\\bags of fun.avi")
'38 MB'
>>> get_size("d:\\media\\bags of fun.avi","KB")
'38,763 KB'
>>> get_size("d:\\media\\bags of fun.avi","kb")
'310,104 kb'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.