"reprlib" --- 대안 "repr()" 구현
********************************

**소스 코드:** Lib/reprlib.py

======================================================================

"reprlib" 모듈은 결과 문자열의 크기에 제한이 있는 객체 표현을 생성하는
수단을 제공합니다. 파이썬 디버거에서 사용되며 다른 문맥에서도 유용할
수 있습니다.

이 모듈은 클래스, 인스턴스 및 함수를 제공합니다.:

class reprlib.Repr(*, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, maxother=30, fillvalue='...', indent=None)

   내장 "repr()"과 유사한 함수를 구현하는 데 유용한 포매팅 서비스를 제
   공하는 클래스; 과도하게 긴 표현의 생성을 피하고자 객체 형별로 크기
   제한이 추가됩니다.

   The keyword arguments of the constructor can be used as a shortcut
   to set the attributes of the "Repr" instance. Which means that the
   following initialization:

      aRepr = reprlib.Repr(maxlevel=3)

   Is equivalent to:

      aRepr = reprlib.Repr()
      aRepr.maxlevel = 3

   See section Repr Objects for more information about "Repr"
   attributes.

   버전 3.12에서 변경: Allow attributes to be set via keyword
   arguments.

reprlib.aRepr

   아래에 설명된 "repr()"로 함수를 제공하는 데 사용되는 "Repr"의 인스
   턴스입니다. 이 객체의 어트리뷰트를 변경하면 "repr()"과 파이썬 디버
   거에서 사용되는 크기 제한에 영향을 줍니다.

reprlib.repr(obj)

   "aRepr"의 "repr()" 메서드입니다. 같은 이름의 내장 함수에 의해 반환
   된 것과 비슷한 문자열을 반환하지만, 대부분의 크기에는 제한이 있습니
   다.

크기 제한 도구 외에도, 모듈은 "__repr__()"에 대한 재귀 호출을 감지하고
대신 자리 표시자 문자열을 치환하는 데코레이터를 제공합니다.

@reprlib.recursive_repr(fillvalue='...')

   같은 스레드 내에서의 재귀 호출을 감지하는 "__repr__()" 메서드용 데
   코레이터. 재귀 호출이 이루어지면, *fillvalue*가 반환되고, 그렇지 않
   으면 평상시의 "__repr__()" 호출이 수행됩니다. 예를 들어:

      >>> from reprlib import recursive_repr
      >>> class MyList(list):
      ...     @recursive_repr()
      ...     def __repr__(self):
      ...         return '<' + '|'.join(map(repr, self)) + '>'
      ...
      >>> m = MyList('abc')
      >>> m.append(m)
      >>> m.append('x')
      >>> print(m)
      <'a'|'b'|'c'|...|'x'>

   Added in version 3.2.


Repr 객체
=========

"Repr" 인스턴스는 여러 객체 형의 표현에 대한 크기 제한과 특정 객체 형
을 포맷하는 메서드를 제공하는데 사용될 수 있습니다.

Repr.fillvalue

   This string is displayed for recursive references. It defaults to
   "...".

   Added in version 3.11.

Repr.maxlevel

   재귀적 표현의 생성에 대한 심도 한계. 기본값은 "6"입니다.

Repr.maxdict
Repr.maxlist
Repr.maxtuple
Repr.maxset
Repr.maxfrozenset
Repr.maxdeque
Repr.maxarray

   명명된 객체 형을 표현하는 항목 수 제한. 기본값은 "maxdict"은 "4",
   "maxarray"는 "5" 이고 그 외는 "6"입니다.

Repr.maxlong

   정수 표현의 최대 문자 수입니다. 숫자는 가운데에서 삭제됩니다. 기본
   값은 "40"입니다.

Repr.maxstring

   문자열 표현의 문자 수 제한. 문자열의 "통상" 표현이 문자 소스로써 사
   용되는 것에 주의해 주세요: 표현에 이스케이프 시퀀스가 필요하면, 표
   현이 짧아질 때 이것이 망가질 수 있습니다. 기본값은 "30"입니다.

Repr.maxother

   이 제한은 "Repr" 객체에서 구체적인 포맷 메서드를 사용할 수 없는 객
   체 형의 크기를 제어하는 데 사용됩니다. "maxstring"과 비슷한 방식으
   로 적용됩니다. 기본값은 "20"입니다.

Repr.indent

   If this attribute is set to "None" (the default), the output is
   formatted with no line breaks or indentation, like the standard
   "repr()". For example:

      >>> example = [
      ...     1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']
      >>> import reprlib
      >>> aRepr = reprlib.Repr()
      >>> print(aRepr.repr(example))
      [1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']

   If "indent" is set to a string, each recursion level is placed on
   its own line, indented by that string:

      >>> aRepr.indent = '-->'
      >>> print(aRepr.repr(example))
      [
      -->1,
      -->'spam',
      -->{
      -->-->'a': 2,
      -->-->'b': 'spam eggs',
      -->-->'c': {
      -->-->-->3: 4.5,
      -->-->-->6: [],
      -->-->},
      -->},
      -->'ham',
      ]

   Setting "indent" to a positive integer value behaves as if it was
   set to a string with that number of spaces:

      >>> aRepr.indent = 4
      >>> print(aRepr.repr(example))
      [
          1,
          'spam',
          {
              'a': 2,
              'b': 'spam eggs',
              'c': {
                  3: 4.5,
                  6: [],
              },
          },
          'ham',
      ]

   Added in version 3.12.

Repr.repr(obj)

   인스턴스에 의해 부과된 포매팅을 사용하는 내장 "repr()"와 등등합니다
   .

Repr.repr1(obj, level)

   "repr()"에서 사용되는 재귀적 구현. *obj*의 형을 사용하여 호출할 포
   매팅 메서드를 결정하고, *obj* 와 *level*을 전달합니다. 형별 메서드
   는 재귀적 포매팅을 수행하기 위해 "repr1()"을 호출해야 하는데, 재귀
   호출에서 *level* 값으로 "level - 1"을 사용합니다.

Repr.repr_TYPE(obj, level)

   특정 형의 포매팅 메서드는 형 이름에 기반하는 이름의 메서드로 구현됩
   니다. 메서드 이름에서, **TYPE** 은
   "'_'.join(type(obj).__name__.split())"으로 치환됩니다. 이 메서드로
   의 디스패치는 "repr1()"에 의해 처리됩니다. 재귀적으로 값을 포맷해야
   하는 형별 메서드는 "self.repr1(subobj, level - 1)"을 호출해야 합니
   다.


Repr 객체 서브 클래싱
=====================

"Repr.repr1()"에 의한 동적 디스패치의 사용은 "Repr"의 서브 클래스가 추
가 내장 객체 형에 대한 지원을 추가하거나 이미 지원되는 형의 처리를 수
정할 수 있도록 합니다. 이 예제는 파일 객체에 대한 특별한 지원이 어떻게
추가될 수 있는지 보여줍니다:

   import reprlib
   import sys

   class MyRepr(reprlib.Repr):

       def repr_TextIOWrapper(self, obj, level):
           if obj.name in {'<stdin>', '<stdout>', '<stderr>'}:
               return obj.name
           return repr(obj)

   aRepr = MyRepr()
   print(aRepr.repr(sys.stdin))         # '<stdin>' 을 인쇄합니다

   <stdin>
